WW-3046 Make "redirect" result support params (passed from <param>), like "redirectAction" does

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@755605 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Musachy Barroso
2009-03-18 14:36:33 +00:00
parent 62d9bcfc25
commit 526580cc2d
3 changed files with 145 additions and 52 deletions
@@ -131,9 +131,6 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
protected String actionName;
protected String namespace;
protected String method;
protected boolean supressEmptyParameters = false;
private Map<String, String> requestParameters = new LinkedHashMap<String, String>();
public ServletActionRedirectResult() {
super();
@@ -154,9 +151,6 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
this.method = method;
}
protected List<String> prohibitedResultParam = Arrays.asList(new String[] {
DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location",
"prependServletContext", "supressEmptyParameters" });
/**
* @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
@@ -175,27 +169,7 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
method = conditionalParse(method, invocation);
}
String resultCode = invocation.getResultCode();
if (resultCode != null) {
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(
resultCode);
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));
String potentialValue = e.getValue() == null ? "": conditionalParse(e.getValue().toString(), invocation);
if (!supressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0))) {
requestParameters.put(e.getKey().toString(), potentialValue);
}
}
}
}
StringBuilder tmpLocation = new StringBuilder(actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null)));
UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
setLocation(tmpLocation.toString());
@@ -229,29 +203,9 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
this.method = method;
}
/**
* Sets the supressEmptyParameters option
*
* @param suppress The new value for this option
*/
public void setSupressEmptyParameters(boolean supressEmptyParameters) {
this.supressEmptyParameters = supressEmptyParameters;
protected List<String> getProhibitedResultParams() {
return Arrays.asList(new String[]{
DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location",
"prependServletContext", "supressEmptyParameters"});
}
/**
* Adds a request parameter to be added to the redirect url
*
* @param key The parameter name
* @param value The parameter value
*/
public ServletActionRedirectResult addParameter(String key, Object value) {
requestParameters.put(key, String.valueOf(value));
return this;
}
public void handle(ReflectionException ex) {
// Only log as debug as they are probably parameters to be appended to the url
LOG.debug(ex.getMessage(), ex);
}
}
@@ -26,16 +26,25 @@ import javax.servlet.http.HttpServletResponse;
import static javax.servlet.http.HttpServletResponse.*;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.views.util.UrlHelper;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.opensymphony.xwork2.util.reflection.ReflectionException;
import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
import java.io.IOException;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Arrays;
/**
@@ -81,7 +90,7 @@ import java.io.IOException;
* <!-- END SNIPPET: example --></pre>
*
*/
public class ServletRedirectResult extends StrutsResultSupport {
public class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler {
private static final long serialVersionUID = 6316947346435301270L;
@@ -93,6 +102,10 @@ public class ServletRedirectResult extends StrutsResultSupport {
protected int statusCode = SC_FOUND;
protected boolean supressEmptyParameters = false;
protected Map<String, String> requestParameters = new LinkedHashMap<String, String>();
public ServletRedirectResult() {
super();
}
@@ -153,7 +166,26 @@ public class ServletRedirectResult extends StrutsResultSupport {
finalLocation = request.getContextPath() + finalLocation;
}
finalLocation = response.encodeRedirectURL(finalLocation);
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 (!getProhibitedResultParams().contains(e.getKey())) {
requestParameters.put(e.getKey().toString(),
e.getValue() == null ? "" :
conditionalParse(e.getValue().toString(), invocation));
String potentialValue = e.getValue() == null ? "" : conditionalParse(e.getValue().toString(), invocation);
if (!supressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0))) {
requestParameters.put(e.getKey().toString(), potentialValue);
}
}
}
StringBuilder tmpLocation = new StringBuilder(finalLocation);
UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
finalLocation = response.encodeRedirectURL(tmpLocation.toString());
}
if (LOG.isDebugEnabled()) {
@@ -163,6 +195,13 @@ public class ServletRedirectResult extends StrutsResultSupport {
sendRedirect(response, finalLocation);
}
protected List<String> getProhibitedResultParams() {
return Arrays.asList(new String[]{
DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location",
"prependServletContext", "supressEmptyParameters"});
}
/**
* Sends the redirection. Can be overridden to customize how the redirect is handled (i.e. to use a different
* status code)
@@ -189,4 +228,29 @@ public class ServletRedirectResult extends StrutsResultSupport {
// either before the port, or after the protocol
return (url.indexOf(':') == -1);
}
/**
* Sets the supressEmptyParameters option
*
* @param suppress The new value for this option
*/
public void setSupressEmptyParameters(boolean supressEmptyParameters) {
this.supressEmptyParameters = supressEmptyParameters;
}
/**
* Adds a request parameter to be added to the redirect url
*
* @param key The parameter name
* @param value The parameter value
*/
public ServletRedirectResult addParameter(String key, Object value) {
requestParameters.put(key, String.valueOf(value));
return this;
}
public void handle(ReflectionException ex) {
// Only log as debug as they are probably parameters to be appended to the url
LOG.debug(ex.getMessage(), ex);
}
}
@@ -22,6 +22,7 @@
package org.apache.struts2.dispatcher;
import java.util.HashMap;
import java.util.Map;
import java.io.StringWriter;
import java.io.PrintWriter;
@@ -34,15 +35,23 @@ import ognl.Ognl;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.StrutsTestCase;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import com.mockobjects.dynamic.C;
import com.mockobjects.dynamic.Mock;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import com.opensymphony.xwork2.util.ValueStackFactory;
@@ -138,6 +147,59 @@ public class ServletRedirectResultTest extends StrutsTestCase implements StrutsS
responseMock.verify();
}
public void testIncludeParameterInResult() throws Exception {
ResultConfig resultConfig = new ResultConfig.Builder("", "")
.addParam("namespace", "someNamespace")
.addParam("encode", "true")
.addParam("parse", "true")
.addParam("location", "someLocation")
.addParam("prependServletContext", "true")
.addParam("method", "someMethod")
.addParam("param1", "value 1")
.addParam("param2", "value 2")
.addParam("param3", "value 3")
.build();
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<String, ResultConfig> results= new HashMap<String, ResultConfig>();
results.put("myResult", resultConfig);
ActionConfig actionConfig = new ActionConfig.Builder("", "", "")
.addResultConfigs(results).build();
ServletRedirectResult result = new ServletRedirectResult();
result.setLocation("/myNamespace/myAction.action");
result.setParse(false);
result.setEncode(false);
result.setPrependServletContext(false);
IMocksControl control = EasyMock.createControl();
ActionProxy mockActionProxy = control.createMock(ActionProxy.class);
ActionInvocation mockInvocation = control.createMock(ActionInvocation.class);
mockInvocation.getProxy();
control.andReturn(mockActionProxy);
mockInvocation.getResultCode();
control.andReturn("myResult");
mockActionProxy.getConfig();
control.andReturn(actionConfig);
mockInvocation.getInvocationContext();
control.andReturn(context);
control.replay();
result.setActionMapper(container.getInstance(ActionMapper.class));
result.execute(mockInvocation);
assertEquals("/myNamespace/myAction.action?param1=value+1&param2=value+2&param3=value+3", res.getRedirectedUrl());
control.verify();
}
protected void setUp() throws Exception {
super.setUp();
configurationManager.getConfiguration().
@@ -151,11 +213,24 @@ public class ServletRedirectResultTest extends StrutsTestCase implements StrutsS
requestMock = new Mock(HttpServletRequest.class);
requestMock.matchAndReturn("getContextPath", "/context");
ResultConfig resultConfig = new ResultConfig.Builder("", "").build();
Map<String, ResultConfig> results= new HashMap<String, ResultConfig>();
results.put("myResult", resultConfig);
ActionConfig actionConfig = new ActionConfig.Builder("", "", "")
.addResultConfigs(results).build();
ActionContext ac = new ActionContext(Ognl.createDefaultContext(null));
ac.put(ServletActionContext.HTTP_REQUEST, requestMock.proxy());
ac.put(ServletActionContext.HTTP_RESPONSE, responseMock.proxy());
MockActionInvocation ai = new MockActionInvocation();
ai.setInvocationContext(ac);
ai.setResultCode("myResult");
ActionProxy mockActionProxy = EasyMock.createNiceMock(ActionProxy.class);
ai.setProxy(mockActionProxy);
EasyMock.expect(mockActionProxy.getConfig()).andReturn(actionConfig).anyTimes();
EasyMock.replay(mockActionProxy);
this.ai = ai;
ai.setStack(ActionContext.getContext().getValueStack());
}