Anonymous avatar Anonymous committed 4e23f44

- added "redirect-action should be able to accept parameters" support

Issue number: WW-1329
Obtained from:
Submitted by:
Reviewed by:

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@2668 573baa09-0c28-0410-bef9-dab3c582ae83

Comments (0)

Files changed (3)

src/java/com/opensymphony/webwork/dispatcher/ServletActionRedirectResult.java

 package com.opensymphony.webwork.dispatcher;
 
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import com.opensymphony.webwork.dispatcher.mapper.ActionMapper;
 import com.opensymphony.webwork.views.util.UrlHelper;
 
 import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.config.entities.ActionConfig;
+import com.opensymphony.xwork.config.entities.ResultConfig;
 
 /**
  * <!-- START SNIPPET: description -->
  * configuration files. This means you can change your URL patterns at any point and your application will still work.
  * It is strongly recommended that if you are redirecting to another action, you use this result rather than the
  * standard redirect result.
+ * 
+ * <p/>
+ * 
+ * To pass parameters, the &lt;param&gt; ... &lt;/param&gt; tag. The following parameters will not be 
+ * passable becuase they are part of the config param for this particular result.
+ * 
+ * <ul>
+ * 	<li>actionName</li>
+ *  <li>namespace</li>
+ *  <li>method</li>
+ *  <li>encode</li>
+ *  <li>parse</li>
+ *  <li>location</li>
+ *  <li>prependServletContext</li>
+ * </ul>
+ * 
+ * See examples below for an example of how request parameters could be passed in.
  *
  * <!-- END SNIPPET: description -->
  *
  *         &lt;result&gt;error.jsp&lt;/result&gt;
  *     &lt;/action&gt;
  * &lt;/package&gt;
+ * 
+ * <package name="passingRequestParameters" extends="webwork-default" namespace="/passingRequestParameters">
+ * 	  <-- Pass parameters (reportType, width and height) -->
+ *    <!-- 
+ *    The redirect-action url generated will be : 
+ *    /genReport/generateReport.action?reportType=pie&width=100&height=100
+ *    -->
+ *    <action name="gatherReportInfo" class="...">
+ *       <result name="showReportResult" type="redirect-action">
+ *       	<param name="actionName">generateReport</param>
+ *          <param name="namespace=">/genReport</param>
+ *          <param name="reportType">pie</param>
+ *          <param name="width">100</param>
+ *          <param name="height">100</param>
+ *       </result>
+ *    </action>
+ * </package>
+ * 
  * <!-- END SNIPPET: example --></pre>
  *
  * @see ActionMapper
  */
 public class ServletActionRedirectResult extends ServletRedirectResult {
-    public static final String DEFAULT_PARAM = "actionName";
+	
+	private static final long serialVersionUID = -6126889518132056284L;
+
+	public static final String DEFAULT_PARAM = "actionName";
 
     protected String actionName;
     protected String namespace;
     protected String method;
+    
+    protected List prohibitedResultParam = Arrays.asList(new String[] { 
+    		DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", 
+    		"prependServletContext" });
 
     public void execute(ActionInvocation invocation) throws Exception {
         actionName = conditionalParse(actionName, invocation);
         else {
         	method = conditionalParse(method, invocation);
         }
-
+        
+        Map requestParameters = new HashMap();
+        ResultConfig resultConfig = (ResultConfig) invocation.getProxy().getConfig().getResults().get(
+        		invocation.getResultCode());
+        Map resultConfigParams = resultConfig.getParams();
+        for (Iterator i = resultConfigParams.entrySet().iterator(); i.hasNext(); ) {
+        	Map.Entry e = (Map.Entry) i.next();
+        	if (! prohibitedResultParam.contains(e.getKey())) {
+        		requestParameters.put(e.getKey().toString(), 
+        				e.getValue() == null ? "": 
+        					conditionalParse(e.getValue().toString(), invocation));
+        	}
+        }
+        
         ActionMapper mapper = ActionMapperFactory.getMapper();
-        location = mapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null));
+        StringBuffer tmpLocation = new StringBuffer(mapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null)));
+        UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
+        
+        location = tmpLocation.toString();
 
         super.execute(invocation);
     }

src/java/com/opensymphony/webwork/views/util/UrlHelper.java

 
         return result;
     }
-
+    
     public static void buildParametersString(Map params, StringBuffer link) {
+    	buildParametersString(params, link, AMP);
+    }
+
+    public static void buildParametersString(Map params, StringBuffer link, String paramSeparator) {
         if ((params != null) && (params.size() > 0)) {
             if (link.toString().indexOf("?") == -1) {
                 link.append("?");
             } else {
-                link.append(AMP);
+                link.append(paramSeparator);
             }
 
             // Set params
                     }
 
                     if (i < (values.length - 1)) {
-                        link.append(AMP);
+                        link.append(paramSeparator);
                     }
                 }
 
                 if (iter.hasNext()) {
-                    link.append(AMP);
+                    link.append(paramSeparator);
                 }
             }
         }

src/test/com/opensymphony/webwork/dispatcher/ServletActionRedirectResultTest.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.webwork.dispatcher;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.webwork.WebWorkTestCase;
+import com.opensymphony.webwork.dispatcher.ServletActionRedirectResult;
+
+import org.easymock.MockControl;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+import com.opensymphony.xwork.ActionContext;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.ActionProxy;
+import com.opensymphony.xwork.config.entities.ActionConfig;
+import com.opensymphony.xwork.config.entities.ResultConfig;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+/**
+ * 
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class ServletActionRedirectResultTest extends WebWorkTestCase {
+	
+	public void testIncludeParameterInResultWithConditionParseOn() throws Exception {
+		
+		ResultConfig resultConfig = new ResultConfig();
+		resultConfig.addParam("actionName", "someActionName");
+		resultConfig.addParam("namespace", "someNamespace");
+		resultConfig.addParam("encode", "true");
+		resultConfig.addParam("parse", "true");
+		resultConfig.addParam("location", "someLocation");
+		resultConfig.addParam("prependServletContext", "true");
+		resultConfig.addParam("method", "someMethod");
+		resultConfig.addParam("param1", "${#value1}");
+		resultConfig.addParam("param2", "${#value2}");
+		resultConfig.addParam("param3", "${#value3}");
+		
+		ActionContext context = ActionContext.getContext();
+		OgnlValueStack stack = context.getValueStack();
+		context.put("value1", "value 1");
+		context.put("value2", "value 2");
+		context.put("value3", "value 3");
+		MockHttpServletRequest req = new MockHttpServletRequest();
+		MockHttpServletResponse res = new MockHttpServletResponse();
+		context.put(ServletActionContext.HTTP_REQUEST, req);
+		context.put(ServletActionContext.HTTP_RESPONSE, res);
+		
+		
+		Map results=  new HashMap();
+		results.put("myResult", resultConfig);
+		
+		ActionConfig actionConfig = new ActionConfig();
+		actionConfig.setResults(results);
+		
+		ServletActionRedirectResult result = new ServletActionRedirectResult();
+		result.setActionName("myAction");
+		result.setNamespace("/myNamespace");
+		result.setParse(false);
+		result.setEncode(false);
+		result.setPrependServletContext(false);
+		
+		MockControl actionProxyControl = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) actionProxyControl.getMock();
+		mockActionProxy.getConfig();
+		actionProxyControl.setDefaultReturnValue(actionConfig);
+		
+		MockControl actionInvocationControl = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockInvocation = (ActionInvocation) actionInvocationControl.getMock();
+		mockInvocation.getProxy();
+		actionInvocationControl.setDefaultReturnValue(mockActionProxy);
+		mockInvocation.getResultCode();
+		actionInvocationControl.setDefaultReturnValue("myResult");
+		mockInvocation.getInvocationContext();
+		actionInvocationControl.setDefaultReturnValue(context);
+		mockInvocation.getStack();
+		actionInvocationControl.setDefaultReturnValue(stack);
+		
+		
+		actionProxyControl.replay();
+		actionInvocationControl.replay();
+		
+		result.execute(mockInvocation);
+		assertEquals("/myNamespace/myAction.action?param2=value+2&param1=value+1&param3=value+3", res.getRedirectedUrl());
+		
+		actionProxyControl.verify();
+		actionInvocationControl.verify();
+	}
+	
+	
+	
+	public void testIncludeParameterInResult() throws Exception {
+		
+		ResultConfig resultConfig = new ResultConfig();
+		resultConfig.addParam("actionName", "someActionName");
+		resultConfig.addParam("namespace", "someNamespace");
+		resultConfig.addParam("encode", "true");
+		resultConfig.addParam("parse", "true");
+		resultConfig.addParam("location", "someLocation");
+		resultConfig.addParam("prependServletContext", "true");
+		resultConfig.addParam("method", "someMethod");
+		resultConfig.addParam("param1", "value 1");
+		resultConfig.addParam("param2", "value 2");
+		resultConfig.addParam("param3", "value 3");
+		
+		ActionContext context = ActionContext.getContext();
+		MockHttpServletRequest req = new MockHttpServletRequest();
+		MockHttpServletResponse res = new MockHttpServletResponse();
+		context.put(ServletActionContext.HTTP_REQUEST, req);
+		context.put(ServletActionContext.HTTP_RESPONSE, res);
+		
+		
+		Map results=  new HashMap();
+		results.put("myResult", resultConfig);
+		
+		ActionConfig actionConfig = new ActionConfig();
+		actionConfig.setResults(results);
+		
+		ServletActionRedirectResult result = new ServletActionRedirectResult();
+		result.setActionName("myAction");
+		result.setNamespace("/myNamespace");
+		result.setParse(false);
+		result.setEncode(false);
+		result.setPrependServletContext(false);
+		
+		MockControl actionProxyControl = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) actionProxyControl.getMock();
+		mockActionProxy.getConfig();
+		actionProxyControl.setDefaultReturnValue(actionConfig);
+		
+		MockControl actionInvocationControl = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockInvocation = (ActionInvocation) actionInvocationControl.getMock();
+		mockInvocation.getProxy();
+		actionInvocationControl.setDefaultReturnValue(mockActionProxy);
+		mockInvocation.getResultCode();
+		actionInvocationControl.setDefaultReturnValue("myResult");
+		mockInvocation.getInvocationContext();
+		actionInvocationControl.setDefaultReturnValue(context);
+		
+		actionProxyControl.replay();
+		actionInvocationControl.replay();
+		
+		result.execute(mockInvocation);
+		assertEquals("/myNamespace/myAction.action?param2=value+2&param1=value+1&param3=value+3", res.getRedirectedUrl());
+		
+		actionProxyControl.verify();
+		actionInvocationControl.verify();
+	}
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.