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