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 java.util.Arrays;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.apache.struts2.dispatcher.mapper.ActionMapper;
31 import org.apache.struts2.dispatcher.mapper.ActionMapping;
32 import org.apache.struts2.views.util.UrlHelper;
33
34 import com.opensymphony.xwork2.ActionInvocation;
35 import com.opensymphony.xwork2.config.entities.ResultConfig;
36 import com.opensymphony.xwork2.inject.Inject;
37
38 /***
39 * <!-- START SNIPPET: description -->
40 *
41 * This result uses the {@link ActionMapper} provided by the {@link ActionMapperFactory} to redirect the browser to a
42 * URL that invokes the specified action and (optional) namespace. This is better than the {@link ServletRedirectResult}
43 * because it does not require you to encode the URL patterns processed by the {@link ActionMapper} in to your struts.xml
44 * configuration files. This means you can change your URL patterns at any point and your application will still work.
45 * It is strongly recommended that if you are redirecting to another action, you use this result rather than the
46 * standard redirect result.
47 *
48 * <p/>
49 *
50 * See examples below for an example of how request parameters could be passed in.
51 *
52 * <!-- END SNIPPET: description -->
53 *
54 * <b>This result type takes the following parameters:</b>
55 *
56 * <!-- START SNIPPET: params -->
57 *
58 * <ul>
59 *
60 * <li><b>actionName (default)</b> - the name of the action that will be redirect to</li>
61 *
62 * <li><b>namespace</b> - used to determine which namespace the action is in that we're redirecting to . If namespace is
63 * null, this defaults to the current namespace</li>
64 *
65 * </ul>
66 *
67 * <!-- END SNIPPET: params -->
68 *
69 * <b>Example:</b>
70 *
71 * <pre><!-- START SNIPPET: example -->
72 * <package name="public" extends="struts-default">
73 * <action name="login" class="...">
74 * <!-- Redirect to another namespace -->
75 * <result type="redirect-action">
76 * <param name="actionName">dashboard</param>
77 * <param name="namespace">/secure</param>
78 * </result>
79 * </action>
80 * </package>
81 *
82 * <package name="secure" extends="struts-default" namespace="/secure">
83 * <-- Redirect to an action in the same namespace -->
84 * <action name="dashboard" class="...">
85 * <result>dashboard.jsp</result>
86 * <result name="error" type="redirect-action>error</result>
87 * </action>
88 *
89 * <action name="error" class="...">
90 * <result>error.jsp</result>
91 * </action>
92 * </package>
93 *
94 * <package name="passingRequestParameters" extends="struts-default" namespace="/passingRequestParameters">
95 * <-- Pass parameters (reportType, width and height) -->
96 * <!--
97 * The redirect-action url generated will be :
98 * /genReport/generateReport.action?reportType=pie&width=100&height=100
99 * -->
100 * <action name="gatherReportInfo" class="...">
101 * <result name="showReportResult" type="redirect-action">
102 * <param name="actionName">generateReport</param>
103 * <param name="namespace">/genReport</param>
104 * <param name="reportType">pie</param>
105 * <param name="width">100</param>
106 * <param name="height">100</param>
107 * </result>
108 * </action>
109 * </package>
110 *
111 *
112 * <!-- END SNIPPET: example --></pre>
113 *
114 * @see ActionMapper
115 */
116 public class ServletActionRedirectResult extends ServletRedirectResult {
117
118 private static final long serialVersionUID = -9042425229314584066L;
119
120 /*** The default parameter */
121 public static final String DEFAULT_PARAM = "actionName";
122
123 protected String actionName;
124 protected String namespace;
125 protected String method;
126
127 private Map<String, String> requestParameters = new LinkedHashMap<String, String>();
128
129 public ServletActionRedirectResult() {
130 super();
131 }
132
133 public ServletActionRedirectResult(String actionName) {
134 this(null, actionName, null);
135 }
136
137 public ServletActionRedirectResult(String actionName, String method) {
138 this(null, actionName, method);
139 }
140
141 public ServletActionRedirectResult(String namespace, String actionName, String method) {
142 super(null);
143 this.namespace = namespace;
144 this.actionName = actionName;
145 this.method = method;
146 }
147
148 protected List<String> prohibitedResultParam = Arrays.asList(new String[] {
149 DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location",
150 "prependServletContext" });
151
152 /***
153 * @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
154 */
155 public void execute(ActionInvocation invocation) throws Exception {
156 actionName = conditionalParse(actionName, invocation);
157 if (namespace == null) {
158 namespace = invocation.getProxy().getNamespace();
159 } else {
160 namespace = conditionalParse(namespace, invocation);
161 }
162 if (method == null) {
163 method = "";
164 }
165 else {
166 method = conditionalParse(method, invocation);
167 }
168
169 String resultCode = invocation.getResultCode();
170 if (resultCode != null) {
171 ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(
172 resultCode);
173 Map resultConfigParams = resultConfig.getParams();
174 for (Iterator i = resultConfigParams.entrySet().iterator(); i.hasNext(); ) {
175 Map.Entry e = (Map.Entry) i.next();
176 if (! prohibitedResultParam.contains(e.getKey())) {
177 requestParameters.put(e.getKey().toString(),
178 e.getValue() == null ? "":
179 conditionalParse(e.getValue().toString(), invocation));
180 }
181 }
182 }
183
184 StringBuffer tmpLocation = new StringBuffer(actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null)));
185 UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
186
187 setLocation(tmpLocation.toString());
188
189 super.execute(invocation);
190 }
191
192 /***
193 * Sets the action name
194 *
195 * @param actionName The name
196 */
197 public void setActionName(String actionName) {
198 this.actionName = actionName;
199 }
200
201 /***
202 * Sets the namespace
203 *
204 * @param namespace The namespace
205 */
206 public void setNamespace(String namespace) {
207 this.namespace = namespace;
208 }
209
210 /***
211 * Sets the method
212 *
213 * @param method The method
214 */
215 public void setMethod(String method) {
216 this.method = method;
217 }
218
219 /***
220 * Adds a request parameter to be added to the redirect url
221 *
222 * @param key The parameter name
223 * @param value The parameter value
224 */
225 public ServletActionRedirectResult addParameter(String key, Object value) {
226 requestParameters.put(key, String.valueOf(value));
227 return this;
228 }
229
230 }