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.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.struts2.ServletActionContext;
26 import org.apache.struts2.dispatcher.mapper.ActionMapperFactory;
27
28 import com.opensymphony.xwork2.ActionContext;
29 import com.opensymphony.xwork2.ActionInvocation;
30
31
32 /***
33 * <!-- START SNIPPET: description -->
34 *
35 * Calls the {@link HttpServletResponse#sendRedirect(String) sendRedirect}
36 * method to the location specified. The response is told to redirect the
37 * browser to the specified location (a new request from the client). The
38 * consequence of doing this means that the action (action instance, action
39 * errors, field errors, etc) that was just executed is lost and no longer
40 * available. This is because actions are built on a single-thread model. The
41 * only way to pass data is through the session or with web parameters
42 * (url?name=value) which can be OGNL expressions.
43 *
44 * <!-- END SNIPPET: description -->
45 * <p/>
46 * <b>This result type takes the following parameters:</b>
47 *
48 * <!-- START SNIPPET: params -->
49 *
50 * <ul>
51 *
52 * <li><b>location (default)</b> - the location to go to after execution.</li>
53 *
54 * <li><b>parse</b> - true by default. If set to false, the location param will
55 * not be parsed for Ognl expressions.</li>
56 *
57 * </ul>
58 *
59 * <p>
60 * This result follows the same rules from {@link StrutsResultSupport}.
61 * </p>
62 *
63 * <!-- END SNIPPET: params -->
64 *
65 * <b>Example:</b>
66 *
67 * <pre><!-- START SNIPPET: example -->
68 * <result name="success" type="redirect">
69 * <param name="location">foo.jsp</param>
70 * <param name="parse">false</param>
71 * </result>
72 * <!-- END SNIPPET: example --></pre>
73 *
74 */
75 public class ServletRedirectResult extends StrutsResultSupport {
76
77 private static final long serialVersionUID = 6316947346435301270L;
78
79 private static final Log log = LogFactory.getLog(ServletRedirectResult.class);
80
81 protected boolean prependServletContext = true;
82
83 public ServletRedirectResult() {
84 super();
85 }
86
87 public ServletRedirectResult(String location) {
88 super(location);
89 }
90
91 /***
92 * Sets whether or not to prepend the servlet context path to the redirected URL.
93 *
94 * @param prependServletContext <tt>true</tt> to prepend the location with the servlet context path,
95 * <tt>false</tt> otherwise.
96 */
97 public void setPrependServletContext(boolean prependServletContext) {
98 this.prependServletContext = prependServletContext;
99 }
100
101 /***
102 * Redirects to the location specified by calling {@link HttpServletResponse#sendRedirect(String)}.
103 *
104 * @param finalLocation the location to redirect to.
105 * @param invocation an encapsulation of the action execution state.
106 * @throws Exception if an error occurs when redirecting.
107 */
108 protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
109 ActionContext ctx = invocation.getInvocationContext();
110 HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
111 HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
112
113 if (isPathUrl(finalLocation)) {
114 if (!finalLocation.startsWith("/")) {
115 String namespace = ActionMapperFactory.getMapper().getMapping(
116 request, Dispatcher.getInstance().getConfigurationManager()).getNamespace();
117
118 if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace))) {
119 finalLocation = namespace + "/" + finalLocation;
120 } else {
121 finalLocation = "/" + finalLocation;
122 }
123 }
124
125
126 if (prependServletContext && (request.getContextPath() != null) && (request.getContextPath().length() > 0)) {
127 finalLocation = request.getContextPath() + finalLocation;
128 }
129
130 finalLocation = response.encodeRedirectURL(finalLocation);
131 }
132
133 if (log.isDebugEnabled()) {
134 log.debug("Redirecting to finalLocation " + finalLocation);
135 }
136
137 response.sendRedirect(finalLocation);
138 }
139
140 private static boolean isPathUrl(String url) {
141
142
143
144 return (url.indexOf(':') == -1);
145 }
146 }