1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.dispatcher;
23
24 import java.util.Map;
25
26 import javax.servlet.RequestDispatcher;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29 import javax.servlet.jsp.PageContext;
30
31 import org.apache.struts2.ServletActionContext;
32 import org.apache.struts2.views.util.UrlHelper;
33
34 import com.opensymphony.xwork2.ActionInvocation;
35 import com.opensymphony.xwork2.util.logging.Logger;
36 import com.opensymphony.xwork2.util.logging.LoggerFactory;
37
38
39 /***
40 * <!-- START SNIPPET: description -->
41 *
42 * Includes or forwards to a view (usually a jsp). Behind the scenes Struts
43 * will use a RequestDispatcher, where the target servlet/JSP receives the same
44 * request/response objects as the original servlet/JSP. Therefore, you can pass
45 * data between them using request.setAttribute() - the Struts action is
46 * available.
47 * <p/>
48 * There are three possible ways the result can be executed:
49 *
50 * <ul>
51 *
52 * <li>If we are in the scope of a JSP (a PageContext is available), PageContext's
53 * {@link PageContext#include(String) include} method is called.</li>
54 *
55 * <li>If there is no PageContext and we're not in any sort of include (there is no
56 * "javax.servlet.include.servlet_path" in the request attributes), then a call to
57 * {@link RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) forward}
58 * is made.</li>
59 *
60 * <li>Otherwise, {@link RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) include}
61 * is called.</li>
62 *
63 * </ul>
64 * <!-- END SNIPPET: description -->
65 *
66 * <b>This result type takes the following parameters:</b>
67 *
68 * <!-- START SNIPPET: params -->
69 *
70 * <ul>
71 *
72 * <li><b>location (default)</b> - the location to go to after execution (ex. jsp).</li>
73 *
74 * <li><b>parse</b> - true by default. If set to false, the location param will not be parsed for Ognl expressions.</li>
75 *
76 * </ul>
77 *
78 * <!-- END SNIPPET: params -->
79 *
80 * <b>Example:</b>
81 *
82 * <pre><!-- START SNIPPET: example -->
83 * <result name="success" type="dispatcher">
84 * <param name="location">foo.jsp</param>
85 * </result>
86 * <!-- END SNIPPET: example --></pre>
87 *
88 * This result follows the same rules from {@link StrutsResultSupport}.
89 *
90 * @see javax.servlet.RequestDispatcher
91 */
92 public class ServletDispatcherResult extends StrutsResultSupport {
93
94 private static final long serialVersionUID = -1970659272360685627L;
95
96 private static final Logger LOG = LoggerFactory.getLogger(ServletDispatcherResult.class);
97
98 public ServletDispatcherResult() {
99 super();
100 }
101
102 public ServletDispatcherResult(String location) {
103 super(location);
104 }
105
106 /***
107 * Dispatches to the given location. Does its forward via a RequestDispatcher. If the
108 * dispatch fails a 404 error will be sent back in the http response.
109 *
110 * @param finalLocation the location to dispatch to.
111 * @param invocation the execution state of the action
112 * @throws Exception if an error occurs. If the dispatch fails the error will go back via the
113 * HTTP request.
114 */
115 public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
116 if (LOG.isDebugEnabled()) {
117 LOG.debug("Forwarding to location " + finalLocation);
118 }
119
120 PageContext pageContext = ServletActionContext.getPageContext();
121
122 if (pageContext != null) {
123 pageContext.include(finalLocation);
124 } else {
125 HttpServletRequest request = ServletActionContext.getRequest();
126 HttpServletResponse response = ServletActionContext.getResponse();
127 RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
128
129
130
131 if (invocation != null && finalLocation != null && finalLocation.length() > 0
132 && finalLocation.indexOf("?") > 0) {
133 String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
134 Map parameters = (Map) invocation.getInvocationContext().getContextMap().get("parameters");
135 Map queryParams = UrlHelper.parseQueryString(queryString, true);
136 if (queryParams != null && !queryParams.isEmpty())
137 parameters.putAll(queryParams);
138 }
139
140
141 if (dispatcher == null) {
142 response.sendError(404, "result '" + finalLocation + "' not found");
143
144 return;
145 }
146
147
148
149
150 if (!response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) {
151 request.setAttribute("struts.view_uri", finalLocation);
152 request.setAttribute("struts.request_uri", request.getRequestURI());
153
154 dispatcher.forward(request, response);
155 } else {
156 dispatcher.include(request, response);
157 }
158 }
159 }
160 }