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