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