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