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