mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
WW-3777 converts UrlHelper into an interface with default implementation, cleanups code and adds support for generics
git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1303298 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -223,4 +223,8 @@ public final class StrutsConstants {
|
||||
|
||||
/** Enables caching of parsed OGNL expressions **/
|
||||
public static final String STRUTS_ENABLE_OGNL_EXPRESSION_CACHE = "struts.ognl.enableExpressionCache";
|
||||
|
||||
/** The{@link org.apache.struts2.views.util.UrlHelper} implementation class **/
|
||||
public static final String STRUTS_URL_HELPER = "struts.view.urlHelper";
|
||||
|
||||
}
|
||||
|
||||
@@ -21,19 +21,11 @@
|
||||
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.StrutsException;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.util.FastByteArrayOutputStream;
|
||||
@@ -41,9 +33,14 @@ import org.apache.struts2.views.jsp.TagUtils;
|
||||
import org.apache.struts2.views.util.ContextUtil;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Base class to extend for UI components.
|
||||
@@ -52,12 +49,14 @@ import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
*
|
||||
*/
|
||||
public class Component {
|
||||
|
||||
public static final String COMPONENT_STACK = "__component_stack";
|
||||
|
||||
protected ValueStack stack;
|
||||
protected Map parameters;
|
||||
protected ActionMapper actionMapper;
|
||||
protected boolean throwExceptionOnELFailure;
|
||||
private UrlHelper urlHelper;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -91,7 +90,11 @@ public class Component {
|
||||
public void setThrowExceptionsOnELFailure(String throwException) {
|
||||
this.throwExceptionOnELFailure = "true".equals(throwException);
|
||||
}
|
||||
|
||||
|
||||
@Inject
|
||||
public void setUrlHelper(UrlHelper urlHelper) {
|
||||
this.urlHelper = urlHelper;
|
||||
}
|
||||
/**
|
||||
* Gets the OGNL value stack assoicated with this component.
|
||||
* @return the OGNL value stack assoicated with this component.
|
||||
@@ -407,7 +410,7 @@ public class Component {
|
||||
String finalNamespace = determineNamespace(namespace, getStack(), req);
|
||||
ActionMapping mapping = new ActionMapping(finalAction, finalNamespace, finalMethod, parameters);
|
||||
String uri = actionMapper.getUriFromActionMapping(mapping);
|
||||
return UrlHelper.buildUrl(uri, req, res, parameters, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, escapeAmp);
|
||||
return urlHelper.buildUrl(uri, req, res, parameters, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, escapeAmp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -445,8 +448,8 @@ public class Component {
|
||||
stack.push(parameters);
|
||||
stack.push(this);
|
||||
try {
|
||||
for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
for (Object o : params.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) o;
|
||||
String key = (String) entry.getKey();
|
||||
stack.setValue(key, entry.getValue());
|
||||
}
|
||||
|
||||
@@ -27,16 +27,15 @@ import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -51,12 +50,17 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ServletUrlRenderer.class);
|
||||
|
||||
private ActionMapper actionMapper;
|
||||
private UrlHelper urlHelper;
|
||||
|
||||
@Inject
|
||||
public void setActionMapper(ActionMapper mapper) {
|
||||
this.actionMapper = mapper;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setUrlHelper(UrlHelper urlHelper) {
|
||||
this.urlHelper = urlHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@@ -87,7 +91,7 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
if (_value != null && _value.indexOf("?") > 0) {
|
||||
_value = _value.substring(0, _value.indexOf("?"));
|
||||
}
|
||||
result = UrlHelper.buildUrl(_value, urlComponent.getHttpServletRequest(), urlComponent.getHttpServletResponse(), urlComponent.getParameters(), scheme, urlComponent.isIncludeContext(), urlComponent.isEncode(), urlComponent.isForceAddSchemeHostAndPort(), urlComponent.isEscapeAmp());
|
||||
result = urlHelper.buildUrl(_value, urlComponent.getHttpServletRequest(), urlComponent.getHttpServletResponse(), urlComponent.getParameters(), scheme, urlComponent.isIncludeContext(), urlComponent.isEncode(), urlComponent.isForceAddSchemeHostAndPort(), urlComponent.isEscapeAmp());
|
||||
}
|
||||
String anchor = urlComponent.getAnchor();
|
||||
if (StringUtils.isNotEmpty(anchor)) {
|
||||
@@ -121,8 +125,7 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void renderFormUrl(Form formComponent) {
|
||||
String namespace = formComponent.determineNamespace(formComponent.namespace, formComponent.getStack(),
|
||||
formComponent.request);
|
||||
String namespace = formComponent.determineNamespace(formComponent.namespace, formComponent.getStack(), formComponent.request);
|
||||
String action;
|
||||
|
||||
if(formComponent.action != null) {
|
||||
@@ -151,8 +154,8 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
if (actionConfig != null) {
|
||||
|
||||
ActionMapping mapping = new ActionMapping(actionName, namespace, actionMethod, formComponent.parameters);
|
||||
String result = UrlHelper.buildUrl(formComponent.actionMapper.getUriFromActionMapping(mapping),
|
||||
formComponent.request, formComponent.response, null, null, formComponent.includeContext, true);
|
||||
String result = urlHelper.buildUrl(formComponent.actionMapper.getUriFromActionMapping(mapping),
|
||||
formComponent.request, formComponent.response, null, null, formComponent.includeContext, true);
|
||||
formComponent.addParameter("action", result);
|
||||
|
||||
// let's try to get the actual action class and name
|
||||
@@ -187,7 +190,7 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
LOG.warn("No configuration found for the specified action: '" + actionName + "' in namespace: '" + namespace + "'. Form action defaulting to 'action' attribute's literal value.");
|
||||
}
|
||||
|
||||
String result = UrlHelper.buildUrl(action, formComponent.request, formComponent.response, null, null, formComponent.includeContext, true);
|
||||
String result = urlHelper.buildUrl(action, formComponent.request, formComponent.response, null, null, formComponent.includeContext, true);
|
||||
formComponent.addParameter("action", result);
|
||||
|
||||
// namespace: cut out anything between the start and the last /
|
||||
@@ -236,7 +239,7 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
}
|
||||
|
||||
if (UrlProvider.NONE.equalsIgnoreCase(includeParams)) {
|
||||
mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), Collections.EMPTY_MAP);
|
||||
mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), Collections.<String, Object>emptyMap());
|
||||
} else if (UrlProvider.ALL.equalsIgnoreCase(includeParams)) {
|
||||
mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), urlComponent.getHttpServletRequest().getParameterMap());
|
||||
|
||||
@@ -267,7 +270,7 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
}
|
||||
private void includeGetParameters(UrlProvider urlComponent) {
|
||||
String query = extractQueryString(urlComponent);
|
||||
mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), UrlHelper.parseQueryString(query));
|
||||
mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), urlHelper.parseQueryString(query));
|
||||
}
|
||||
|
||||
private String extractQueryString(UrlProvider urlComponent) {
|
||||
@@ -304,9 +307,9 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
* @param parameters component parameters
|
||||
* @param contextParameters request parameters
|
||||
*/
|
||||
protected void mergeRequestParameters(String value, Map parameters, Map contextParameters){
|
||||
protected void mergeRequestParameters(String value, Map<String, Object> parameters, Map<String, Object> contextParameters){
|
||||
|
||||
Map mergedParams = new LinkedHashMap(contextParameters);
|
||||
Map<String, Object> mergedParams = new LinkedHashMap<String, Object>(contextParameters);
|
||||
|
||||
// Merge contextParameters (from current request) with parameters specified in value attribute
|
||||
// eg. value="someAction.action?id=someId&venue=someVenue"
|
||||
@@ -315,30 +318,23 @@ public class ServletUrlRenderer implements UrlRenderer {
|
||||
if (value != null && value.trim().length() > 0 && value.indexOf("?") > 0) {
|
||||
String queryString = value.substring(value.indexOf("?")+1);
|
||||
|
||||
mergedParams = UrlHelper.parseQueryString(queryString);
|
||||
for (Iterator iterator = contextParameters.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
Object key = entry.getKey();
|
||||
|
||||
if (!mergedParams.containsKey(key)) {
|
||||
mergedParams.put(key, entry.getValue());
|
||||
mergedParams = urlHelper.parseQueryString(queryString);
|
||||
for (Map.Entry<String, Object> entry : contextParameters.entrySet()) {
|
||||
if (!mergedParams.containsKey(entry.getKey())) {
|
||||
mergedParams.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Merge parameters specified in value attribute
|
||||
// eg. value="someAction.action?id=someId&venue=someVenue"
|
||||
// with parameters specified though param tag
|
||||
// eg. <param name="id" value="%{'someId'}" />
|
||||
// where parameters specified through param tag takes priority.
|
||||
|
||||
for (Iterator iterator = mergedParams.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
Object key = entry.getKey();
|
||||
|
||||
if (!parameters.containsKey(key)) {
|
||||
parameters.put(key, entry.getValue());
|
||||
for (Map.Entry<String, Object> entry : mergedParams.entrySet()) {
|
||||
if (!parameters.containsKey(entry.getKey())) {
|
||||
parameters.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,6 @@
|
||||
|
||||
package org.apache.struts2.config;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.components.UrlRenderer;
|
||||
import org.apache.struts2.dispatcher.StaticContentLoader;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
|
||||
import org.apache.struts2.views.freemarker.FreemarkerManager;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
|
||||
import com.opensymphony.xwork2.ActionProxyFactory;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.TextProvider;
|
||||
@@ -46,13 +35,27 @@ import com.opensymphony.xwork2.inject.ContainerBuilder;
|
||||
import com.opensymphony.xwork2.inject.Context;
|
||||
import com.opensymphony.xwork2.inject.Factory;
|
||||
import com.opensymphony.xwork2.inject.Scope;
|
||||
import com.opensymphony.xwork2.util.*;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import com.opensymphony.xwork2.util.LocalizedTextUtil;
|
||||
import com.opensymphony.xwork2.util.PatternMatcher;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import com.opensymphony.xwork2.util.location.LocatableProperties;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionContextFactory;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
|
||||
import com.opensymphony.xwork2.validator.ActionValidatorManager;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.components.UrlRenderer;
|
||||
import org.apache.struts2.dispatcher.StaticContentLoader;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
|
||||
import org.apache.struts2.views.freemarker.FreemarkerManager;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Selects the implementations of key framework extension points, using the loaded
|
||||
@@ -178,7 +181,9 @@ import com.opensymphony.xwork2.validator.ActionValidatorManager;
|
||||
* </ul>
|
||||
*/
|
||||
public class BeanSelectionProvider implements ConfigurationProvider {
|
||||
|
||||
public static final String DEFAULT_BEAN_NAME = "struts";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BeanSelectionProvider.class);
|
||||
|
||||
public void destroy() {
|
||||
@@ -191,7 +196,6 @@ public class BeanSelectionProvider implements ConfigurationProvider {
|
||||
|
||||
public void init(Configuration configuration) throws ConfigurationException {
|
||||
// NO-OP
|
||||
|
||||
}
|
||||
|
||||
public boolean needsReload() {
|
||||
@@ -216,6 +220,7 @@ public class BeanSelectionProvider implements ConfigurationProvider {
|
||||
alias(PatternMatcher.class, StrutsConstants.STRUTS_PATTERNMATCHER, builder, props);
|
||||
alias(StaticContentLoader.class, StrutsConstants.STRUTS_STATIC_CONTENT_LOADER, builder, props);
|
||||
alias(UnknownHandlerManager.class, StrutsConstants.STRUTS_UNKNOWN_HANDLER_MANAGER, builder, props);
|
||||
alias(UrlHelper.class, StrutsConstants.STRUTS_URL_HELPER, builder, props);
|
||||
|
||||
if ("true".equalsIgnoreCase(props.getProperty(StrutsConstants.STRUTS_DEVMODE))) {
|
||||
props.setProperty(StrutsConstants.STRUTS_I18N_RELOAD, "true");
|
||||
@@ -271,7 +276,7 @@ public class BeanSelectionProvider implements ConfigurationProvider {
|
||||
String foundName = props.getProperty(key, DEFAULT_BEAN_NAME);
|
||||
if (builder.contains(type, foundName)) {
|
||||
if (LOG.isInfoEnabled()) {
|
||||
LOG.info("Choosing bean ("+foundName+") for "+type);
|
||||
LOG.info("Choosing bean (" + foundName + ") for " + type);
|
||||
}
|
||||
builder.alias(type, foundName, Container.DEFAULT_NAME);
|
||||
} else {
|
||||
@@ -305,8 +310,10 @@ public class BeanSelectionProvider implements ConfigurationProvider {
|
||||
}
|
||||
|
||||
static class ObjectFactoryDelegateFactory implements Factory {
|
||||
|
||||
String name;
|
||||
Class type;
|
||||
|
||||
ObjectFactoryDelegateFactory(String name, Class type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
@@ -320,5 +327,7 @@ public class BeanSelectionProvider implements ConfigurationProvider {
|
||||
throw new ConfigurationException("Unable to load bean "+type.getName()+" ("+name+")");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,20 +21,17 @@
|
||||
|
||||
package org.apache.struts2.dispatcher;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
*
|
||||
*
|
||||
* This result uses the {@link ActionMapper} provided by the
|
||||
* {@link ActionMapperFactory} to redirect the browser to a URL that invokes the
|
||||
* specified action and (optional) namespace. This is better than the
|
||||
@@ -44,40 +41,40 @@ import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* See examples below for an example of how request parameters could be passed
|
||||
* in.
|
||||
*
|
||||
*
|
||||
* <!-- END SNIPPET: description -->
|
||||
*
|
||||
*
|
||||
* <b>This result type takes the following parameters:</b>
|
||||
*
|
||||
*
|
||||
* <!-- START SNIPPET: params -->
|
||||
*
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
*
|
||||
* <li><b>actionName (default)</b> - The name of the action that will be
|
||||
* redirected to.</li>
|
||||
*
|
||||
*
|
||||
* <li><b>namespace</b> - Used to determine which namespace the action is in
|
||||
* that we're redirecting to. If namespace is null, the default will be the
|
||||
* current namespace.</li>
|
||||
*
|
||||
*
|
||||
* <li><b>suppressEmptyParameters</b> - Optional boolean (defaults to false) that
|
||||
* can prevent parameters with no values from being included in the redirect
|
||||
* URL.</li>
|
||||
*
|
||||
* <li><b>parse</b> - Boolean, true by default. If set to false, the actionName
|
||||
* <li><b>parse</b> - Boolean, true by default. If set to false, the actionName
|
||||
* param will not be parsed for Ognl expressions.</li>
|
||||
*
|
||||
* <li><b>anchor</b> - Optional. Also known as "fragment" or colloquially as
|
||||
* <li><b>anchor</b> - Optional. Also known as "fragment" or colloquially as
|
||||
* "hash". You can specify an anchor for a result.</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* <!-- END SNIPPET: params -->
|
||||
*
|
||||
*
|
||||
* <b>Example:</b>
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <package name="public" extends="struts-default">
|
||||
@@ -89,19 +86,19 @@ import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
|
||||
* </result>
|
||||
* </action>
|
||||
* </package>
|
||||
*
|
||||
*
|
||||
* <package name="secure" extends="struts-default" namespace="/secure">
|
||||
* <-- Redirect to an action in the same namespace -->
|
||||
* <action name="dashboard" class="...">
|
||||
* <result>dashboard.jsp</result>
|
||||
* <result name="error" type="redirectAction">error</result>
|
||||
* </action>
|
||||
*
|
||||
*
|
||||
* <action name="error" class="...">
|
||||
* <result>error.jsp</result>
|
||||
* </action>
|
||||
* </package>
|
||||
*
|
||||
*
|
||||
* <package name="passingRequestParameters" extends="struts-default" namespace="/passingRequestParameters">
|
||||
* <!-- Pass parameters (reportType, width and height) -->
|
||||
* <!--
|
||||
@@ -121,18 +118,18 @@ import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
|
||||
* </result>
|
||||
* </action>
|
||||
* </package>
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @see ActionMapper
|
||||
*/
|
||||
public class ServletActionRedirectResult extends ServletRedirectResult implements ReflectionExceptionHandler {
|
||||
|
||||
private static final long serialVersionUID = -9042425229314584066L;
|
||||
|
||||
/** The default parameter */
|
||||
/* The default parameter */
|
||||
public static final String DEFAULT_PARAM = "actionName";
|
||||
|
||||
protected String actionName;
|
||||
@@ -165,68 +162,55 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
|
||||
/**
|
||||
* @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
|
||||
*/
|
||||
public void execute(ActionInvocation invocation) throws Exception
|
||||
{
|
||||
public void execute(ActionInvocation invocation) throws Exception {
|
||||
actionName = conditionalParse(actionName, invocation);
|
||||
if (namespace == null)
|
||||
{
|
||||
if (namespace == null) {
|
||||
namespace = invocation.getProxy().getNamespace();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
namespace = conditionalParse(namespace, invocation);
|
||||
}
|
||||
if (method == null)
|
||||
{
|
||||
if (method == null) {
|
||||
method = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
method = conditionalParse(method, invocation);
|
||||
}
|
||||
|
||||
StringBuilder tmpLocation = new StringBuilder(actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null)));
|
||||
String tmpLocation = actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null));
|
||||
|
||||
setLocation(tmpLocation.toString());
|
||||
setLocation(tmpLocation);
|
||||
|
||||
super.execute(invocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action name
|
||||
*
|
||||
* @param actionName
|
||||
* The name
|
||||
*
|
||||
* @param actionName The name
|
||||
*/
|
||||
public void setActionName(String actionName)
|
||||
{
|
||||
public void setActionName(String actionName) {
|
||||
this.actionName = actionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the namespace
|
||||
*
|
||||
* @param namespace
|
||||
* The namespace
|
||||
*
|
||||
* @param namespace The namespace
|
||||
*/
|
||||
public void setNamespace(String namespace)
|
||||
{
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the method
|
||||
*
|
||||
* @param method
|
||||
* The method
|
||||
*
|
||||
* @param method The method
|
||||
*/
|
||||
public void setMethod(String method)
|
||||
{
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
protected List<String> getProhibitedResultParams()
|
||||
{
|
||||
protected List<String> getProhibitedResultParams() {
|
||||
return Arrays.asList(DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", "prependServletContext", "suppressEmptyParameters", "anchor");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
package org.apache.struts2.dispatcher;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
@@ -95,6 +97,8 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ServletDispatcherResult.class);
|
||||
|
||||
private UrlHelper urlHelper;
|
||||
|
||||
public ServletDispatcherResult() {
|
||||
super();
|
||||
}
|
||||
@@ -103,6 +107,11 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
super(location);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setUrlHelper(UrlHelper urlHelper) {
|
||||
this.urlHelper = urlHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches to the given location. Does its forward via a RequestDispatcher. If the
|
||||
* dispatch fails a 404 error will be sent back in the http response.
|
||||
@@ -128,11 +137,10 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
|
||||
//add parameters passed on the location to #parameters
|
||||
// see WW-2120
|
||||
if (invocation != null && finalLocation != null && finalLocation.length() > 0
|
||||
&& finalLocation.indexOf("?") > 0) {
|
||||
if (StringUtils.isNotEmpty(finalLocation) && finalLocation.indexOf("?") > 0) {
|
||||
String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
|
||||
Map parameters = (Map) invocation.getInvocationContext().getContextMap().get("parameters");
|
||||
Map queryParams = UrlHelper.parseQueryString(queryString, true);
|
||||
Map<String, Object> parameters = getParameters(invocation);
|
||||
Map<String, Object> queryParams = urlHelper.parseQueryString(queryString, true);
|
||||
if (queryParams != null && !queryParams.isEmpty())
|
||||
parameters.putAll(queryParams);
|
||||
}
|
||||
@@ -140,7 +148,6 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
// if the view doesn't exist, let's do a 404
|
||||
if (dispatcher == null) {
|
||||
response.sendError(404, "result '" + finalLocation + "' not found");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -160,4 +167,10 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getParameters(ActionInvocation invocation) {
|
||||
return (Map<String, Object>) invocation.getInvocationContext().getContextMap().get("parameters");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -100,17 +100,14 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ServletRedirectResult.class);
|
||||
|
||||
protected boolean prependServletContext = true;
|
||||
|
||||
protected ActionMapper actionMapper;
|
||||
|
||||
protected int statusCode = SC_FOUND;
|
||||
|
||||
protected boolean suppressEmptyParameters = false;
|
||||
|
||||
protected Map<String, String> requestParameters = new LinkedHashMap<String, String>();
|
||||
|
||||
protected Map<String, Object> requestParameters = new LinkedHashMap<String, Object>();
|
||||
protected String anchor;
|
||||
|
||||
private UrlHelper urlHelper;
|
||||
|
||||
public ServletRedirectResult() {
|
||||
super();
|
||||
}
|
||||
@@ -125,13 +122,16 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setActionMapper(ActionMapper mapper)
|
||||
{
|
||||
public void setActionMapper(ActionMapper mapper) {
|
||||
this.actionMapper = mapper;
|
||||
}
|
||||
|
||||
public void setStatusCode(int code)
|
||||
{
|
||||
@Inject
|
||||
public void setUrlHelper(UrlHelper urlHelper) {
|
||||
this.urlHelper = urlHelper;
|
||||
}
|
||||
|
||||
public void setStatusCode(int code) {
|
||||
this.statusCode = code;
|
||||
}
|
||||
|
||||
@@ -140,8 +140,7 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
*
|
||||
* @param anchor
|
||||
*/
|
||||
public void setAnchor(String anchor)
|
||||
{
|
||||
public void setAnchor(String anchor) {
|
||||
this.anchor = anchor;
|
||||
}
|
||||
|
||||
@@ -149,22 +148,16 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
* Sets whether or not to prepend the servlet context path to the redirected
|
||||
* URL.
|
||||
*
|
||||
* @param prependServletContext
|
||||
* <tt>true</tt> to prepend the location with the servlet context
|
||||
* path, <tt>false</tt> otherwise.
|
||||
* @param prependServletContext <tt>true</tt> to prepend the location with the servlet context path, <tt>false</tt> otherwise.
|
||||
*/
|
||||
public void setPrependServletContext(boolean prependServletContext)
|
||||
{
|
||||
public void setPrependServletContext(boolean prependServletContext) {
|
||||
this.prependServletContext = prependServletContext;
|
||||
}
|
||||
|
||||
public void execute(ActionInvocation invocation) throws Exception
|
||||
{
|
||||
if (anchor != null)
|
||||
{
|
||||
public void execute(ActionInvocation invocation) throws Exception {
|
||||
if (anchor != null) {
|
||||
anchor = conditionalParse(anchor, invocation);
|
||||
}
|
||||
|
||||
super.execute(invocation);
|
||||
}
|
||||
|
||||
@@ -172,58 +165,43 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
* Redirects to the location specified by calling
|
||||
* {@link HttpServletResponse#sendRedirect(String)}.
|
||||
*
|
||||
* @param finalLocation
|
||||
* the location to redirect to.
|
||||
* @param invocation
|
||||
* an encapsulation of the action execution state.
|
||||
* @throws Exception
|
||||
* if an error occurs when redirecting.
|
||||
* @param finalLocation the location to redirect to.
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @throws Exception if an error occurs when redirecting.
|
||||
*/
|
||||
protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception
|
||||
{
|
||||
protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
|
||||
ActionContext ctx = invocation.getInvocationContext();
|
||||
HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
|
||||
HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
|
||||
|
||||
if (isPathUrl(finalLocation))
|
||||
{
|
||||
if (!finalLocation.startsWith("/"))
|
||||
{
|
||||
if (isPathUrl(finalLocation)) {
|
||||
if (!finalLocation.startsWith("/")) {
|
||||
ActionMapping mapping = actionMapper.getMapping(request, Dispatcher.getInstance().getConfigurationManager());
|
||||
String namespace = null;
|
||||
if (mapping != null)
|
||||
{
|
||||
if (mapping != null) {
|
||||
namespace = mapping.getNamespace();
|
||||
}
|
||||
|
||||
if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace)))
|
||||
{
|
||||
if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace))) {
|
||||
finalLocation = namespace + "/" + finalLocation;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
finalLocation = "/" + finalLocation;
|
||||
}
|
||||
}
|
||||
|
||||
// if the URL's are relative to the servlet context, append the servlet context path
|
||||
if (prependServletContext && (request.getContextPath() != null) && (request.getContextPath().length() > 0))
|
||||
{
|
||||
if (prependServletContext && (request.getContextPath() != null) && (request.getContextPath().length() > 0)) {
|
||||
finalLocation = request.getContextPath() + finalLocation;
|
||||
}
|
||||
|
||||
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(invocation.getResultCode());
|
||||
if (resultConfig != null)
|
||||
{
|
||||
if (resultConfig != null) {
|
||||
Map<String, String> resultConfigParams = resultConfig.getParams();
|
||||
|
||||
for (Map.Entry<String, String> e : resultConfigParams.entrySet())
|
||||
{
|
||||
if (!getProhibitedResultParams().contains(e.getKey()))
|
||||
{
|
||||
for (Map.Entry<String, String> e : resultConfigParams.entrySet()) {
|
||||
if (!getProhibitedResultParams().contains(e.getKey())) {
|
||||
String potentialValue = e.getValue() == null ? "" : conditionalParse(e.getValue(), invocation);
|
||||
if (!suppressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0)))
|
||||
{
|
||||
if (!suppressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0))) {
|
||||
requestParameters.put(e.getKey(), potentialValue);
|
||||
}
|
||||
}
|
||||
@@ -231,27 +209,24 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
}
|
||||
|
||||
StringBuilder tmpLocation = new StringBuilder(finalLocation);
|
||||
UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
|
||||
urlHelper.buildParametersString(requestParameters, tmpLocation, "&");
|
||||
|
||||
// add the anchor
|
||||
if (anchor != null)
|
||||
{
|
||||
if (anchor != null) {
|
||||
tmpLocation.append('#').append(anchor);
|
||||
}
|
||||
|
||||
finalLocation = response.encodeRedirectURL(tmpLocation.toString());
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Redirecting to finalLocation " + finalLocation);
|
||||
}
|
||||
|
||||
sendRedirect(response, finalLocation);
|
||||
}
|
||||
|
||||
protected List<String> getProhibitedResultParams()
|
||||
{
|
||||
protected List<String> getProhibitedResultParams() {
|
||||
return Arrays.asList(DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", "prependServletContext", "suppressEmptyParameters", "anchor");
|
||||
}
|
||||
|
||||
@@ -259,20 +234,14 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
* Sends the redirection. Can be overridden to customize how the redirect is
|
||||
* handled (i.e. to use a different status code)
|
||||
*
|
||||
* @param response
|
||||
* The response
|
||||
* @param finalLocation
|
||||
* The location URI
|
||||
* @param response The response
|
||||
* @param finalLocation The location URI
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException
|
||||
{
|
||||
if (SC_FOUND == statusCode)
|
||||
{
|
||||
protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException {
|
||||
if (SC_FOUND == statusCode) {
|
||||
response.sendRedirect(finalLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
response.setStatus(statusCode);
|
||||
response.setHeader("Location", finalLocation);
|
||||
response.getWriter().write(finalLocation);
|
||||
@@ -281,8 +250,7 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
|
||||
}
|
||||
|
||||
private static boolean isPathUrl(String url)
|
||||
{
|
||||
private static boolean isPathUrl(String url) {
|
||||
// filter out "http:", "https:", "mailto:", "file:", "ftp:"
|
||||
// since the only valid places for : in URL's is before the path specification
|
||||
// either before the port, or after the protocol
|
||||
@@ -292,31 +260,28 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
|
||||
/**
|
||||
* Sets the suppressEmptyParameters option
|
||||
*
|
||||
* @param suppressEmptyParameters
|
||||
* The new value for this option
|
||||
* @param suppressEmptyParameters The new value for this option
|
||||
*/
|
||||
public void setSuppressEmptyParameters(boolean suppressEmptyParameters)
|
||||
{
|
||||
public void setSuppressEmptyParameters(boolean suppressEmptyParameters) {
|
||||
this.suppressEmptyParameters = suppressEmptyParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a request parameter to be added to the redirect url
|
||||
*
|
||||
* @param key
|
||||
* The parameter name
|
||||
* @param value
|
||||
* The parameter value
|
||||
* @param key The parameter name
|
||||
* @param value The parameter value
|
||||
*/
|
||||
public ServletRedirectResult addParameter(String key, Object value)
|
||||
{
|
||||
public ServletRedirectResult addParameter(String key, Object value) {
|
||||
requestParameters.put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void handle(ReflectionException ex)
|
||||
{
|
||||
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);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,53 +45,49 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Struts base utility class, for use in Velocity and Freemarker templates
|
||||
*
|
||||
*/
|
||||
public class StrutsUtil {
|
||||
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(StrutsUtil.class);
|
||||
|
||||
|
||||
protected HttpServletRequest request;
|
||||
protected HttpServletResponse response;
|
||||
protected Map classes = new Hashtable();
|
||||
protected Map<String, Class> classes = new Hashtable<String, Class>();
|
||||
protected OgnlTool ognl;
|
||||
protected ValueStack stack;
|
||||
|
||||
private UrlHelper urlHelper;
|
||||
private ObjectFactory objectFactory;
|
||||
|
||||
public StrutsUtil(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
|
||||
this.stack = stack;
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.ognl = ((Container)stack.getContext().get(ActionContext.CONTAINER)).getInstance(OgnlTool.class);
|
||||
this.urlHelper = ((Container)stack.getContext().get(ActionContext.CONTAINER)).getInstance(UrlHelper.class);
|
||||
this.objectFactory = ((Container)stack.getContext().get(ActionContext.CONTAINER)).getInstance(ObjectFactory.class);
|
||||
}
|
||||
|
||||
|
||||
public Object bean(Object aName) throws Exception {
|
||||
String name = aName.toString();
|
||||
Class c = (Class) classes.get(name);
|
||||
Class c = classes.get(name);
|
||||
|
||||
if (c == null) {
|
||||
c = ClassLoaderUtil.loadClass(name, StrutsUtil.class);
|
||||
classes.put(name, c);
|
||||
}
|
||||
|
||||
return ObjectFactory.getObjectFactory().buildBean(c, stack.getContext());
|
||||
return objectFactory.buildBean(c, stack.getContext());
|
||||
}
|
||||
|
||||
public boolean isTrue(String expression) {
|
||||
Boolean retVal = (Boolean) stack.findValue(expression, Boolean.class);
|
||||
if (retVal == null) {
|
||||
return false;
|
||||
}
|
||||
return retVal.booleanValue();
|
||||
return retVal != null && retVal;
|
||||
}
|
||||
|
||||
public Object findString(String name) {
|
||||
@@ -134,7 +130,7 @@ public class StrutsUtil {
|
||||
}
|
||||
|
||||
public String buildUrl(String url) {
|
||||
return UrlHelper.buildUrl(url, request, response, null);
|
||||
return urlHelper.buildUrl(url, request, response, null);
|
||||
}
|
||||
|
||||
public Object findValue(String expression, String className) throws ClassNotFoundException {
|
||||
@@ -190,9 +186,8 @@ public class StrutsUtil {
|
||||
Collection items = (Collection) stack.findValue(list);
|
||||
|
||||
if (items != null) {
|
||||
for (Iterator iter = items.iterator(); iter.hasNext();) {
|
||||
Object element = (Object) iter.next();
|
||||
Object key = null;
|
||||
for (Object element : items) {
|
||||
Object key;
|
||||
|
||||
if ((listKey == null) || (listKey.length() == 0)) {
|
||||
key = element;
|
||||
@@ -284,4 +279,5 @@ public class StrutsUtil {
|
||||
writer.write(aByte);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,14 @@
|
||||
|
||||
package org.apache.struts2.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.views.util.DefaultUrlHelper;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@@ -36,11 +37,12 @@ import org.apache.struts2.views.util.UrlHelper;
|
||||
*/
|
||||
public class URLBean {
|
||||
|
||||
HashMap params;
|
||||
HashMap<String, String> params;
|
||||
HttpServletRequest request;
|
||||
HttpServletResponse response;
|
||||
String page;
|
||||
|
||||
private UrlHelper urlHelper;
|
||||
|
||||
public URLBean setPage(String page) {
|
||||
this.page = page;
|
||||
@@ -49,6 +51,7 @@ public class URLBean {
|
||||
|
||||
public void setRequest(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
urlHelper = ServletActionContext.getContext().getInstance(DefaultUrlHelper.class);
|
||||
}
|
||||
|
||||
public void setResponse(HttpServletResponse response) {
|
||||
@@ -57,10 +60,10 @@ public class URLBean {
|
||||
|
||||
public String getURL() {
|
||||
// all this trickier with maps is to reduce the number of objects created
|
||||
Map fullParams = null;
|
||||
Map<String, Object> fullParams = null;
|
||||
|
||||
if (params != null) {
|
||||
fullParams = new HashMap();
|
||||
fullParams = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
if (page == null) {
|
||||
@@ -78,12 +81,12 @@ public class URLBean {
|
||||
fullParams.putAll(params);
|
||||
}
|
||||
|
||||
return UrlHelper.buildUrl(page, request, response, fullParams);
|
||||
return urlHelper.buildUrl(page, request, response, fullParams);
|
||||
}
|
||||
|
||||
public URLBean addParameter(String name, Object value) {
|
||||
if (params == null) {
|
||||
params = new HashMap();
|
||||
params = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.struts2.views.util;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Default implementation of UrlHelper
|
||||
*/
|
||||
public class DefaultUrlHelper implements UrlHelper {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultUrlHelper.class);
|
||||
|
||||
private String encoding = "UTF-8";
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
|
||||
public void setEncoding(String encoding) {
|
||||
if (StringUtils.isNotEmpty(encoding)) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
}
|
||||
|
||||
public String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params) {
|
||||
return buildUrl(action, request, response, params, null, true, true);
|
||||
}
|
||||
|
||||
public String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, String scheme,
|
||||
boolean includeContext, boolean encodeResult) {
|
||||
return buildUrl(action, request, response, params, scheme, includeContext, encodeResult, false);
|
||||
}
|
||||
|
||||
public String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, String scheme,
|
||||
boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort) {
|
||||
return buildUrl(action, request, response, params, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, true);
|
||||
}
|
||||
|
||||
public String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, String scheme,
|
||||
boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort, boolean escapeAmp) {
|
||||
StringBuilder link = new StringBuilder();
|
||||
|
||||
boolean changedScheme = false;
|
||||
|
||||
// FIXME: temporary hack until class is made a properly injected bean
|
||||
Container cont = ActionContext.getContext().getContainer();
|
||||
int httpPort = Integer.parseInt(cont.getInstance(String.class, StrutsConstants.STRUTS_URL_HTTP_PORT));
|
||||
int httpsPort = Integer.parseInt(cont.getInstance(String.class, StrutsConstants.STRUTS_URL_HTTPS_PORT));
|
||||
|
||||
// only append scheme if it is different to the current scheme *OR*
|
||||
// if we explicity want it to be appended by having forceAddSchemeHostAndPort = true
|
||||
if (forceAddSchemeHostAndPort) {
|
||||
String reqScheme = request.getScheme();
|
||||
changedScheme = true;
|
||||
link.append(scheme != null ? scheme : reqScheme);
|
||||
link.append("://");
|
||||
link.append(request.getServerName());
|
||||
|
||||
if (scheme != null) {
|
||||
// If switching schemes, use the configured port for the particular scheme.
|
||||
if (!scheme.equals(reqScheme)) {
|
||||
if ((scheme.equals("http") && (httpPort != DEFAULT_HTTP_PORT)) || (scheme.equals("https") && httpsPort != DEFAULT_HTTPS_PORT)) {
|
||||
link.append(":");
|
||||
link.append(scheme.equals("http") ? httpPort : httpsPort);
|
||||
}
|
||||
// Else use the port from the current request.
|
||||
} else {
|
||||
int reqPort = request.getServerPort();
|
||||
|
||||
if ((scheme.equals("http") && (reqPort != DEFAULT_HTTP_PORT)) || (scheme.equals("https") && reqPort != DEFAULT_HTTPS_PORT)) {
|
||||
link.append(":");
|
||||
link.append(reqPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((scheme != null) && !scheme.equals(request.getScheme())) {
|
||||
changedScheme = true;
|
||||
link.append(scheme);
|
||||
link.append("://");
|
||||
link.append(request.getServerName());
|
||||
|
||||
if ((scheme.equals("http") && (httpPort != DEFAULT_HTTP_PORT)) || (scheme.equals("https") && httpsPort != DEFAULT_HTTPS_PORT))
|
||||
{
|
||||
link.append(":");
|
||||
link.append(scheme.equals("http") ? httpPort : httpsPort);
|
||||
}
|
||||
}
|
||||
|
||||
if (action != null) {
|
||||
// Check if context path needs to be added
|
||||
// Add path to absolute links
|
||||
if (action.startsWith("/") && includeContext) {
|
||||
String contextPath = request.getContextPath();
|
||||
if (!contextPath.equals("/")) {
|
||||
link.append(contextPath);
|
||||
}
|
||||
} else if (changedScheme) {
|
||||
|
||||
// (Applicable to Servlet 2.4 containers)
|
||||
// If the request was forwarded, the attribute below will be set with the original URL
|
||||
String uri = (String) request.getAttribute("javax.servlet.forward.request_uri");
|
||||
|
||||
// If the attribute wasn't found, default to the value in the request object
|
||||
if (uri == null) {
|
||||
uri = request.getRequestURI();
|
||||
}
|
||||
|
||||
link.append(uri.substring(0, uri.lastIndexOf('/') + 1));
|
||||
}
|
||||
|
||||
// Add page
|
||||
link.append(action);
|
||||
} else {
|
||||
// Go to "same page"
|
||||
String requestURI = (String) request.getAttribute("struts.request_uri");
|
||||
|
||||
// (Applicable to Servlet 2.4 containers)
|
||||
// If the request was forwarded, the attribute below will be set with the original URL
|
||||
if (requestURI == null) {
|
||||
requestURI = (String) request.getAttribute("javax.servlet.forward.request_uri");
|
||||
}
|
||||
|
||||
// If neither request attributes were found, default to the value in the request object
|
||||
if (requestURI == null) {
|
||||
requestURI = request.getRequestURI();
|
||||
}
|
||||
|
||||
link.append(requestURI);
|
||||
}
|
||||
|
||||
//if the action was not explicitly set grab the params from the request
|
||||
if (escapeAmp) {
|
||||
buildParametersString(params, link);
|
||||
} else {
|
||||
buildParametersString(params, link, "&");
|
||||
}
|
||||
|
||||
String result = link.toString();
|
||||
|
||||
if (StringUtils.containsIgnoreCase(result, "<script")){
|
||||
result = StringEscapeUtils.escapeEcmaScript(result);
|
||||
}
|
||||
try {
|
||||
result = encodeResult ? response.encodeURL(result) : result;
|
||||
} catch (Exception ex) {
|
||||
// Could not encode the URL for some reason
|
||||
// Use it unchanged
|
||||
result = link.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link) {
|
||||
buildParametersString(params, link, AMP);
|
||||
}
|
||||
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator) {
|
||||
if ((params != null) && (params.size() > 0)) {
|
||||
if (!link.toString().contains("?")) {
|
||||
link.append("?");
|
||||
} else {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
|
||||
// Set params
|
||||
Iterator<Map.Entry<String, Object>> iter = params.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String, Object> entry = iter.next();
|
||||
String name = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (value instanceof Iterable) {
|
||||
for (Iterator iterator = ((Iterable) value).iterator(); iterator
|
||||
.hasNext();) {
|
||||
Object paramValue = iterator.next();
|
||||
link.append(buildParameterSubstring(name, paramValue
|
||||
.toString()));
|
||||
|
||||
if (iterator.hasNext())
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
} else if (value instanceof Object[]) {
|
||||
Object[] array = (Object[]) value;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
Object paramValue = array[i];
|
||||
link.append(buildParameterSubstring(name, paramValue
|
||||
.toString()));
|
||||
|
||||
if (i < array.length - 1)
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
} else {
|
||||
link.append(buildParameterSubstring(name, value != null ? value.toString() : StringUtils.EMPTY));
|
||||
}
|
||||
|
||||
if (iter.hasNext()) {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String buildParameterSubstring(String name, String value) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(translateAndEncode(name));
|
||||
builder.append('=');
|
||||
builder.append(translateAndEncode(value));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates any script expressions using {@link com.opensymphony.xwork2.util.TextParseUtil#translateVariables} and
|
||||
* encodes the URL using {@link java.net.URLEncoder#encode} with the encoding specified in the configuration.
|
||||
*
|
||||
* @param input
|
||||
* @return the translated and encoded string
|
||||
*/
|
||||
public String translateAndEncode(String input) {
|
||||
String translatedInput = translateVariable(input);
|
||||
try {
|
||||
return URLEncoder.encode(translatedInput, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '" + input + "', returning value un-encoded");
|
||||
}
|
||||
return translatedInput;
|
||||
}
|
||||
}
|
||||
|
||||
public String translateAndDecode(String input) {
|
||||
String translatedInput = translateVariable(input);
|
||||
try {
|
||||
return URLDecoder.decode(translatedInput, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '" + input + "', returning value un-encoded");
|
||||
}
|
||||
return translatedInput;
|
||||
}
|
||||
}
|
||||
|
||||
private String translateVariable(String input) {
|
||||
ValueStack valueStack = ServletActionContext.getContext().getValueStack();
|
||||
return TextParseUtil.translateVariables(input, valueStack);
|
||||
}
|
||||
|
||||
public Map<String, Object> parseQueryString(String queryString) {
|
||||
return parseQueryString(queryString, false);
|
||||
}
|
||||
|
||||
public Map<String, Object> parseQueryString(String queryString, boolean forceValueArray) {
|
||||
Map<String, Object> queryParams = new LinkedHashMap<String, Object>();
|
||||
if (queryString != null) {
|
||||
String[] params = queryString.split("&");
|
||||
for (String param : params) {
|
||||
if (param.trim().length() > 0) {
|
||||
String[] tmpParams = param.split("=");
|
||||
String paramName = null;
|
||||
String paramValue = "";
|
||||
if (tmpParams.length > 0) {
|
||||
paramName = tmpParams[0];
|
||||
}
|
||||
if (tmpParams.length > 1) {
|
||||
paramValue = tmpParams[1];
|
||||
}
|
||||
if (paramName != null) {
|
||||
paramName = translateAndDecode(paramName);
|
||||
String translatedParamValue = translateAndDecode(paramValue);
|
||||
|
||||
if (queryParams.containsKey(paramName) || forceValueArray) {
|
||||
// WW-1619 append new param value to existing value(s)
|
||||
Object currentParam = queryParams.get(paramName);
|
||||
if (currentParam instanceof String) {
|
||||
queryParams.put(paramName, new String[]{(String) currentParam, translatedParamValue});
|
||||
} else {
|
||||
String currentParamValues[] = (String[]) currentParam;
|
||||
if (currentParamValues != null) {
|
||||
List<String> paramList = Arrays.asList(currentParamValues);
|
||||
paramList.add(translatedParamValue);
|
||||
queryParams.put(paramName, paramList.toArray(new String[paramList.size()]));
|
||||
} else {
|
||||
queryParams.put(paramName, new String[]{translatedParamValue});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
queryParams.put(paramName, translatedParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return queryParams;
|
||||
}
|
||||
}
|
||||
@@ -1,364 +1,43 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.struts2.views.util;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* UrlHelper
|
||||
*
|
||||
* Helper class used to build Urls or parse request params
|
||||
*/
|
||||
public class UrlHelper {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UrlHelper.class);
|
||||
public interface UrlHelper {
|
||||
|
||||
/**
|
||||
* Default HTTP port (80).
|
||||
*/
|
||||
private static final int DEFAULT_HTTP_PORT = 80;
|
||||
static final int DEFAULT_HTTP_PORT = 80;
|
||||
|
||||
/**
|
||||
* Default HTTPS port (443).
|
||||
*/
|
||||
private static final int DEFAULT_HTTPS_PORT = 443;
|
||||
static final int DEFAULT_HTTPS_PORT = 443;
|
||||
|
||||
private static final String AMP = "&";
|
||||
static final String AMP = "&";
|
||||
|
||||
public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params) {
|
||||
return buildUrl(action, request, response, params, null, true, true);
|
||||
}
|
||||
String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params);
|
||||
|
||||
public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params, String scheme, boolean includeContext, boolean encodeResult) {
|
||||
return buildUrl(action, request, response, params, scheme, includeContext, encodeResult, false);
|
||||
}
|
||||
String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, String scheme,
|
||||
boolean includeContext, boolean encodeResult);
|
||||
|
||||
public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params, String scheme, boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort) {
|
||||
return buildUrl(action, request, response, params, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, true);
|
||||
}
|
||||
String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, String scheme,
|
||||
boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort);
|
||||
|
||||
public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params, String scheme, boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort, boolean escapeAmp) {
|
||||
StringBuilder link = new StringBuilder();
|
||||
String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params, String scheme,
|
||||
boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort, boolean escapeAmp);
|
||||
|
||||
boolean changedScheme = false;
|
||||
void buildParametersString(Map<String, Object> params, StringBuilder link);
|
||||
|
||||
// FIXME: temporary hack until class is made a properly injected bean
|
||||
Container cont = ActionContext.getContext().getContainer();
|
||||
int httpPort = Integer.parseInt(cont.getInstance(String.class, StrutsConstants.STRUTS_URL_HTTP_PORT));
|
||||
int httpsPort = Integer.parseInt(cont.getInstance(String.class, StrutsConstants.STRUTS_URL_HTTPS_PORT));
|
||||
void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator);
|
||||
|
||||
// only append scheme if it is different to the current scheme *OR*
|
||||
// if we explicity want it to be appended by having forceAddSchemeHostAndPort = true
|
||||
if (forceAddSchemeHostAndPort) {
|
||||
String reqScheme = request.getScheme();
|
||||
changedScheme = true;
|
||||
link.append(scheme != null ? scheme : reqScheme);
|
||||
link.append("://");
|
||||
link.append(request.getServerName());
|
||||
Map<String, Object> parseQueryString(String queryString);
|
||||
|
||||
if (scheme != null) {
|
||||
// If switching schemes, use the configured port for the particular scheme.
|
||||
if (!scheme.equals(reqScheme)) {
|
||||
if ((scheme.equals("http") && (httpPort != DEFAULT_HTTP_PORT)) || (scheme.equals("https") && httpsPort != DEFAULT_HTTPS_PORT)) {
|
||||
link.append(":");
|
||||
link.append(scheme.equals("http") ? httpPort : httpsPort);
|
||||
}
|
||||
// Else use the port from the current request.
|
||||
} else {
|
||||
int reqPort = request.getServerPort();
|
||||
Map<String, Object> parseQueryString(String queryString, boolean forceValueArray);
|
||||
|
||||
if ((scheme.equals("http") && (reqPort != DEFAULT_HTTP_PORT)) || (scheme.equals("https") && reqPort != DEFAULT_HTTPS_PORT)) {
|
||||
link.append(":");
|
||||
link.append(reqPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((scheme != null) && !scheme.equals(request.getScheme())) {
|
||||
changedScheme = true;
|
||||
link.append(scheme);
|
||||
link.append("://");
|
||||
link.append(request.getServerName());
|
||||
|
||||
if ((scheme.equals("http") && (httpPort != DEFAULT_HTTP_PORT)) || (scheme.equals("https") && httpsPort != DEFAULT_HTTPS_PORT))
|
||||
{
|
||||
link.append(":");
|
||||
link.append(scheme.equals("http") ? httpPort : httpsPort);
|
||||
}
|
||||
}
|
||||
|
||||
if (action != null) {
|
||||
// Check if context path needs to be added
|
||||
// Add path to absolute links
|
||||
if (action.startsWith("/") && includeContext) {
|
||||
String contextPath = request.getContextPath();
|
||||
if (!contextPath.equals("/")) {
|
||||
link.append(contextPath);
|
||||
}
|
||||
} else if (changedScheme) {
|
||||
|
||||
// (Applicable to Servlet 2.4 containers)
|
||||
// If the request was forwarded, the attribute below will be set with the original URL
|
||||
String uri = (String) request.getAttribute("javax.servlet.forward.request_uri");
|
||||
|
||||
// If the attribute wasn't found, default to the value in the request object
|
||||
if (uri == null) {
|
||||
uri = request.getRequestURI();
|
||||
}
|
||||
|
||||
link.append(uri.substring(0, uri.lastIndexOf('/') + 1));
|
||||
}
|
||||
|
||||
// Add page
|
||||
link.append(action);
|
||||
} else {
|
||||
// Go to "same page"
|
||||
String requestURI = (String) request.getAttribute("struts.request_uri");
|
||||
|
||||
// (Applicable to Servlet 2.4 containers)
|
||||
// If the request was forwarded, the attribute below will be set with the original URL
|
||||
if (requestURI == null) {
|
||||
requestURI = (String) request.getAttribute("javax.servlet.forward.request_uri");
|
||||
}
|
||||
|
||||
// If neither request attributes were found, default to the value in the request object
|
||||
if (requestURI == null) {
|
||||
requestURI = request.getRequestURI();
|
||||
}
|
||||
|
||||
link.append(requestURI);
|
||||
}
|
||||
|
||||
//if the action was not explicitly set grab the params from the request
|
||||
if (escapeAmp) {
|
||||
buildParametersString(params, link);
|
||||
} else {
|
||||
buildParametersString(params, link, "&");
|
||||
}
|
||||
|
||||
String result = link.toString();
|
||||
|
||||
if (StringUtils.containsIgnoreCase(result, "<script")){
|
||||
result = StringEscapeUtils.escapeEcmaScript(result);
|
||||
}
|
||||
try {
|
||||
result = encodeResult ? response.encodeURL(result) : result;
|
||||
} catch (Exception ex) {
|
||||
// Could not encode the URL for some reason
|
||||
// Use it unchanged
|
||||
result = link.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void buildParametersString(Map params, StringBuilder link) {
|
||||
buildParametersString(params, link, AMP);
|
||||
}
|
||||
|
||||
public static void buildParametersString(Map params, StringBuilder link, String paramSeparator) {
|
||||
if ((params != null) && (params.size() > 0)) {
|
||||
if (link.toString().indexOf("?") == -1) {
|
||||
link.append("?");
|
||||
} else {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
|
||||
// Set params
|
||||
Iterator iter = params.entrySet().iterator();
|
||||
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry) iter.next();
|
||||
String name = (String) entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
|
||||
if (value instanceof Iterable) {
|
||||
for (Iterator iterator = ((Iterable) value).iterator(); iterator
|
||||
.hasNext();) {
|
||||
Object paramValue = iterator.next();
|
||||
link.append(buildParameterSubstring(name, paramValue
|
||||
.toString()));
|
||||
|
||||
if (iterator.hasNext())
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
} else if (value instanceof Object[]) {
|
||||
Object[] array = (Object[]) value;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
Object paramValue = array[i];
|
||||
link.append(buildParameterSubstring(name, paramValue
|
||||
.toString()));
|
||||
|
||||
if (i < array.length - 1)
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
} else {
|
||||
link.append(buildParameterSubstring(name, value != null ? value.toString() : StringUtils.EMPTY));
|
||||
}
|
||||
|
||||
if (iter.hasNext())
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String buildParameterSubstring(String name, String value) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(translateAndEncode(name));
|
||||
builder.append('=');
|
||||
builder.append(translateAndEncode(value));
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates any script expressions using {@link com.opensymphony.xwork2.util.TextParseUtil#translateVariables} and
|
||||
* encodes the URL using {@link java.net.URLEncoder#encode} with the encoding specified in the configuration.
|
||||
*
|
||||
* @param input
|
||||
* @return the translated and encoded string
|
||||
*/
|
||||
public static String translateAndEncode(String input) {
|
||||
String translatedInput = translateVariable(input);
|
||||
String encoding = getEncodingFromConfiguration();
|
||||
|
||||
try {
|
||||
return URLEncoder.encode(translatedInput, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '" + input + "', returning value un-encoded");
|
||||
}
|
||||
return translatedInput;
|
||||
}
|
||||
}
|
||||
|
||||
public static String translateAndDecode(String input) {
|
||||
String translatedInput = translateVariable(input);
|
||||
String encoding = getEncodingFromConfiguration();
|
||||
|
||||
try {
|
||||
return URLDecoder.decode(translatedInput, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '" + input + "', returning value un-encoded");
|
||||
}
|
||||
return translatedInput;
|
||||
}
|
||||
}
|
||||
|
||||
private static String translateVariable(String input) {
|
||||
ValueStack valueStack = ServletActionContext.getContext().getValueStack();
|
||||
String output = TextParseUtil.translateVariables(input, valueStack);
|
||||
return output;
|
||||
}
|
||||
|
||||
private static String getEncodingFromConfiguration() {
|
||||
final String encoding;
|
||||
|
||||
// FIXME: temporary hack until class is made a properly injected bean
|
||||
Container cont = ActionContext.getContext().getContainer();
|
||||
String customEncoding = cont.getInstance(String.class, StrutsConstants.STRUTS_I18N_ENCODING);
|
||||
|
||||
if (customEncoding != null) {
|
||||
encoding = customEncoding;
|
||||
} else {
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public static Map parseQueryString(String queryString) {
|
||||
return parseQueryString(queryString, false);
|
||||
}
|
||||
|
||||
public static Map parseQueryString(String queryString, boolean forceValueArray) {
|
||||
Map queryParams = new LinkedHashMap();
|
||||
if (queryString != null) {
|
||||
String[] params = queryString.split("&");
|
||||
for (int a=0; a< params.length; a++) {
|
||||
if (params[a].trim().length() > 0) {
|
||||
String[] tmpParams = params[a].split("=");
|
||||
String paramName = null;
|
||||
String paramValue = "";
|
||||
if (tmpParams.length > 0) {
|
||||
paramName = tmpParams[0];
|
||||
}
|
||||
if (tmpParams.length > 1) {
|
||||
paramValue = tmpParams[1];
|
||||
}
|
||||
if (paramName != null) {
|
||||
paramName = translateAndDecode(paramName);
|
||||
String translatedParamValue = translateAndDecode(paramValue);
|
||||
|
||||
if(queryParams.containsKey(paramName) || forceValueArray) {
|
||||
// WW-1619 append new param value to existing value(s)
|
||||
Object currentParam = queryParams.get(paramName);
|
||||
if(currentParam instanceof String) {
|
||||
queryParams.put(paramName, new String[] {
|
||||
(String) currentParam, translatedParamValue});
|
||||
} else {
|
||||
String currentParamValues[] = (String[]) currentParam;
|
||||
if (currentParamValues != null) {
|
||||
List paramList = new ArrayList(Arrays
|
||||
.asList(currentParamValues));
|
||||
paramList.add(translatedParamValue);
|
||||
String newParamValues[] = new String[paramList
|
||||
.size()];
|
||||
queryParams.put(paramName, paramList
|
||||
.toArray(newParamValues));
|
||||
} else {
|
||||
queryParams.put(paramName, new String[] {translatedParamValue});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
queryParams.put(paramName, translatedParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return queryParams;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
<bean type="com.opensymphony.xwork2.TextProvider" name="struts" class="com.opensymphony.xwork2.TextProviderSupport" scope="default" />
|
||||
|
||||
<bean type="org.apache.struts2.components.UrlRenderer" name="struts" class="org.apache.struts2.components.ServletUrlRenderer"/>
|
||||
<bean type="org.apache.struts2.views.util.UrlHelper" name="struts" class="org.apache.struts2.views.util.DefaultUrlHelper"/>
|
||||
|
||||
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="struts" class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory" />
|
||||
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="struts" class="com.opensymphony.xwork2.ognl.OgnlReflectionProvider" />
|
||||
|
||||
+4
-1
@@ -31,6 +31,7 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsTestCase;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.views.util.DefaultUrlHelper;
|
||||
import org.easymock.IMocksControl;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
@@ -89,6 +90,7 @@ public class ServletActionRedirectResultTest extends StrutsTestCase {
|
||||
result.setEncode(false);
|
||||
result.setPrependServletContext(false);
|
||||
result.setAnchor("fragment");
|
||||
result.setUrlHelper(new DefaultUrlHelper());
|
||||
|
||||
IMocksControl control = createControl();
|
||||
ActionProxy mockActionProxy = control.createMock(ActionProxy.class);
|
||||
@@ -143,6 +145,7 @@ public class ServletActionRedirectResultTest extends StrutsTestCase {
|
||||
result.setEncode(false);
|
||||
result.setPrependServletContext(false);
|
||||
result.setAnchor("fragment");
|
||||
result.setUrlHelper(new DefaultUrlHelper());
|
||||
|
||||
IMocksControl control = createControl();
|
||||
ActionProxy mockActionProxy = control.createMock(ActionProxy.class);
|
||||
@@ -177,7 +180,7 @@ public class ServletActionRedirectResultTest extends StrutsTestCase {
|
||||
.build();
|
||||
|
||||
ObjectFactory factory = container.getInstance(ObjectFactory.class);
|
||||
ServletActionRedirectResult result = (ServletActionRedirectResult) factory.buildResult(resultConfig, new HashMap());
|
||||
ServletActionRedirectResult result = (ServletActionRedirectResult) factory.buildResult(resultConfig, new HashMap<String, Object>());
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,19 +35,24 @@ import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.StrutsTestCase;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import static org.easymock.EasyMock.*;
|
||||
import org.apache.struts2.views.util.DefaultUrlHelper;
|
||||
import org.easymock.IMocksControl;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_SEE_OTHER;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static javax.servlet.http.HttpServletResponse.SC_SEE_OTHER;
|
||||
import static org.easymock.EasyMock.createControl;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
@@ -188,6 +193,7 @@ public class ServletRedirectResultTest extends StrutsTestCase implements StrutsS
|
||||
result.setEncode(false);
|
||||
result.setPrependServletContext(false);
|
||||
result.setAnchor("fragment");
|
||||
result.setUrlHelper(new DefaultUrlHelper());
|
||||
|
||||
IMocksControl control = createControl();
|
||||
ActionProxy mockActionProxy = control.createMock(ActionProxy.class);
|
||||
|
||||
+27
-25
@@ -38,12 +38,13 @@ import java.util.TreeMap;
|
||||
|
||||
|
||||
/**
|
||||
* Test case for UrlHelper.
|
||||
* Test case for DefaultUrlHelper.
|
||||
*
|
||||
*/
|
||||
public class UrlHelperTest extends StrutsTestCase {
|
||||
public class DefaultUrlHelperTest extends StrutsTestCase {
|
||||
|
||||
private StubContainer stubContainer;
|
||||
private DefaultUrlHelper urlHelper;
|
||||
|
||||
public void testForceAddSchemeHostAndPort() throws Exception {
|
||||
String expectedUrl = "http://localhost/contextPath/path1/path2/myAction.action";
|
||||
@@ -57,7 +58,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
|
||||
|
||||
String result = UrlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse)mockHttpServletResponse.proxy(), null, "http", true, true, true);
|
||||
String result = urlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), null, "http", true, true, true);
|
||||
assertEquals(expectedUrl, result);
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
|
||||
|
||||
String result = UrlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest)mockHttpServletRequest.proxy(), (HttpServletResponse)mockHttpServletResponse.proxy(), null, "http", true, true, false);
|
||||
String result = urlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), null, "http", true, true, false);
|
||||
|
||||
assertEquals(expectedUrl, result);
|
||||
}
|
||||
@@ -90,7 +91,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
|
||||
|
||||
String result = UrlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse)mockHttpServletResponse.proxy(), null, "http", true, true, true);
|
||||
String result = urlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), null, "http", true, true, true);
|
||||
assertEquals(expectedUrl, result);
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
@@ -105,7 +106,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
|
||||
StringBuilder url = new StringBuilder("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
|
||||
|
||||
UrlHelper.buildParametersString(parameters, url);
|
||||
urlHelper.buildParametersString(parameters, url);
|
||||
|
||||
assertEquals(
|
||||
expectedUrl, url.toString());
|
||||
@@ -121,7 +122,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
|
||||
StringBuilder url = new StringBuilder("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
|
||||
|
||||
UrlHelper.buildParametersString(parameters, url);
|
||||
urlHelper.buildParametersString(parameters, url);
|
||||
|
||||
assertEquals(
|
||||
expectedUrl, url.toString());
|
||||
@@ -140,10 +141,10 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl,
|
||||
expectedUrl);
|
||||
|
||||
String result = UrlHelper.buildUrl("/path1/path2/myAction.action",
|
||||
(HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), null,
|
||||
null, true, true, true);
|
||||
String result = urlHelper.buildUrl("/path1/path2/myAction.action",
|
||||
(HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), null,
|
||||
null, true, true, true);
|
||||
assertEquals(expectedUrl, result);
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
@@ -158,7 +159,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
|
||||
|
||||
String actualUrl = UrlHelper.buildUrl(expectedUrl, (HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
String actualUrl = urlHelper.buildUrl(expectedUrl, (HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), new HashMap());
|
||||
assertEquals(expectedUrl, actualUrl);
|
||||
}
|
||||
@@ -178,7 +179,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", "world");
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -197,7 +198,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", "world");
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, null, true, true, false, false);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, null, true, true, false, false);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -213,7 +214,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -238,7 +239,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -263,7 +264,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "http", true, true);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "http", true, true);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -292,7 +293,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -321,7 +322,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "http", true, true);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "http", true, true);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
@@ -348,13 +349,13 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
String actionName = "promo.html";
|
||||
Map params = new TreeMap();
|
||||
|
||||
String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
|
||||
String urlString = urlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
|
||||
assertEquals(expectedString, urlString);
|
||||
}
|
||||
|
||||
|
||||
public void testParseQuery() throws Exception {
|
||||
Map result = UrlHelper.parseQueryString("aaa=aaaval&bbb=bbbval&ccc=&%3Ca%22%3E=%3Cval%3E");
|
||||
Map result = urlHelper.parseQueryString("aaa=aaaval&bbb=bbbval&ccc=&%3Ca%22%3E=%3Cval%3E");
|
||||
|
||||
assertEquals(result.get("aaa"), "aaaval");
|
||||
assertEquals(result.get("bbb"), "bbbval");
|
||||
@@ -363,14 +364,14 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
}
|
||||
|
||||
public void testParseEmptyQuery() throws Exception {
|
||||
Map result = UrlHelper.parseQueryString("");
|
||||
Map result = urlHelper.parseQueryString("");
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), 0);
|
||||
}
|
||||
|
||||
public void testParseNullQuery() throws Exception {
|
||||
Map result = UrlHelper.parseQueryString(null);
|
||||
Map result = urlHelper.parseQueryString(null);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), 0);
|
||||
@@ -379,7 +380,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
|
||||
public void testTranslateAndEncode() throws Exception {
|
||||
setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
|
||||
String result = UrlHelper.translateAndEncode("\u65b0\u805e");
|
||||
String result = urlHelper.translateAndEncode("\u65b0\u805e");
|
||||
String expectedResult = "%E6%96%B0%E8%81%9E";
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
@@ -387,7 +388,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
|
||||
public void testTranslateAndDecode() throws Exception {
|
||||
setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
|
||||
String result = UrlHelper.translateAndDecode("%E6%96%B0%E8%81%9E");
|
||||
String result = urlHelper.translateAndDecode("%E6%96%B0%E8%81%9E");
|
||||
String expectedResult = "\u65b0\u805e";
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
@@ -397,6 +398,7 @@ public class UrlHelperTest extends StrutsTestCase {
|
||||
super.setUp();
|
||||
stubContainer = new StubContainer(container);
|
||||
ActionContext.getContext().put(ActionContext.CONTAINER, stubContainer);
|
||||
urlHelper = new DefaultUrlHelper();
|
||||
}
|
||||
|
||||
private void setProp(String key, String val) {
|
||||
@@ -48,13 +48,14 @@ public abstract class JSPRuntime {
|
||||
public static void handle(String location, boolean flush) throws Exception {
|
||||
final HttpServletResponse response = ServletActionContext.getResponse();
|
||||
final HttpServletRequest request = ServletActionContext.getRequest();
|
||||
final UrlHelper urlHelper = ServletActionContext.getContext().getInstance(UrlHelper.class);
|
||||
|
||||
int i = location.indexOf("?");
|
||||
if (i > 0) {
|
||||
//extract params from the url and add them to the request
|
||||
Map parameters = ActionContext.getContext().getParameters();
|
||||
Map<String, Object> parameters = ActionContext.getContext().getParameters();
|
||||
String query = location.substring(i + 1);
|
||||
Map queryParams = UrlHelper.parseQueryString(query, true);
|
||||
Map<String, Object> queryParams = urlHelper.parseQueryString(query, true);
|
||||
if (queryParams != null && !queryParams.isEmpty())
|
||||
parameters.putAll(queryParams);
|
||||
location = location.substring(0, i);
|
||||
|
||||
@@ -28,6 +28,8 @@ import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
|
||||
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.views.util.DefaultUrlHelper;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
import org.easymock.EasyMock;
|
||||
import org.easymock.IAnswer;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
@@ -266,6 +268,10 @@ public class EmbeddedJSPResultTest extends TestCase {
|
||||
//mock container
|
||||
Container container = EasyMock.createNiceMock(Container.class);
|
||||
EasyMock.expect(container.getInstance(XWorkConverter.class)).andReturn(converter).anyTimes();
|
||||
|
||||
UrlHelper urlHelper = new DefaultUrlHelper();
|
||||
EasyMock.expect(container.getInstance(UrlHelper.class)).andReturn(urlHelper).anyTimes();
|
||||
|
||||
EasyMock.replay(container);
|
||||
stackContext.put(ActionContext.CONTAINER, container);
|
||||
actionContext.setContainer(container);
|
||||
|
||||
+31
-30
@@ -28,15 +28,16 @@ import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletMode;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.ServletActionRedirectResult;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -133,14 +134,12 @@ public class PortletActionRedirectResult extends PortletResult {
|
||||
public static final String DEFAULT_PARAM = "actionName";
|
||||
|
||||
protected String actionName;
|
||||
|
||||
protected String namespace;
|
||||
|
||||
protected String method;
|
||||
|
||||
private Map<String, String> requestParameters = new LinkedHashMap<String, String>();
|
||||
|
||||
private Map<String, Object> requestParameters = new LinkedHashMap<String, Object>();
|
||||
private ActionMapper actionMapper;
|
||||
private UrlHelper urlHelper;
|
||||
|
||||
public PortletActionRedirectResult() {
|
||||
super();
|
||||
@@ -161,23 +160,27 @@ public class PortletActionRedirectResult extends PortletResult {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
protected List<String> prohibitedResultParam = Arrays.asList(new String[] { DEFAULT_PARAM, "namespace", "method",
|
||||
"encode", "parse", "location", "prependServletContext" });
|
||||
protected List<String> prohibitedResultParam = Arrays.asList(DEFAULT_PARAM, "namespace", "method", "encode", "parse",
|
||||
"location", "prependServletContext");
|
||||
|
||||
@Inject
|
||||
public void setActionMapper(ActionMapper actionMapper) {
|
||||
this.actionMapper = actionMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
@Inject
|
||||
public void setUrlHelper(UrlHelper urlHelper) {
|
||||
this.urlHelper = urlHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
|
||||
*/
|
||||
public void execute(ActionInvocation invocation) throws Exception {
|
||||
actionName = conditionalParse(actionName, invocation);
|
||||
String portletNamespace = (String)invocation.getInvocationContext().get(PortletActionConstants.PORTLET_NAMESPACE);
|
||||
if (portletMode != null) {
|
||||
Map<PortletMode, String> namespaceMap = (Map<PortletMode, String>) invocation.getInvocationContext().get(
|
||||
PortletActionConstants.MODE_NAMESPACE_MAP);
|
||||
Map<PortletMode, String> namespaceMap = getNamespaceMap(invocation);
|
||||
namespace = namespaceMap.get(portletMode);
|
||||
}
|
||||
if (namespace == null) {
|
||||
@@ -194,30 +197,32 @@ public class PortletActionRedirectResult extends PortletResult {
|
||||
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));
|
||||
}
|
||||
}
|
||||
Map<String, String> resultConfigParams = resultConfig.getParams();
|
||||
for (Map.Entry<String, String> e : resultConfigParams.entrySet()) {
|
||||
if (!prohibitedResultParam.contains(e.getKey())) {
|
||||
requestParameters.put(e.getKey(), e.getValue() == null ? "" : conditionalParse(e.getValue(), invocation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder tmpLocation = new StringBuilder(actionMapper.getUriFromActionMapping(new ActionMapping(actionName,
|
||||
(portletNamespace == null ? namespace : portletNamespace + namespace), method, null)));
|
||||
UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
|
||||
urlHelper.buildParametersString(requestParameters, tmpLocation, "&");
|
||||
|
||||
setLocation(tmpLocation.toString());
|
||||
|
||||
super.execute(invocation);
|
||||
}
|
||||
|
||||
/**
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<PortletMode, String> getNamespaceMap(ActionInvocation invocation) {
|
||||
return (Map<PortletMode, String>) invocation.getInvocationContext().get(PortletActionConstants.MODE_NAMESPACE_MAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action name
|
||||
*
|
||||
* @param actionName
|
||||
* The name
|
||||
* @param actionName The name
|
||||
*/
|
||||
public void setActionName(String actionName) {
|
||||
this.actionName = actionName;
|
||||
@@ -226,8 +231,7 @@ public class PortletActionRedirectResult extends PortletResult {
|
||||
/**
|
||||
* Sets the namespace
|
||||
*
|
||||
* @param namespace
|
||||
* The namespace
|
||||
* @param namespace The namespace
|
||||
*/
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
@@ -236,8 +240,7 @@ public class PortletActionRedirectResult extends PortletResult {
|
||||
/**
|
||||
* Sets the method
|
||||
*
|
||||
* @param method
|
||||
* The method
|
||||
* @param method The method
|
||||
*/
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
@@ -246,10 +249,8 @@ public class PortletActionRedirectResult extends PortletResult {
|
||||
/**
|
||||
* Adds a request parameter to be added to the redirect url
|
||||
*
|
||||
* @param key
|
||||
* The parameter name
|
||||
* @param value
|
||||
* The parameter value
|
||||
* @param key The parameter name
|
||||
* @param value The parameter value
|
||||
*/
|
||||
public PortletActionRedirectResult addParameter(String key, Object value) {
|
||||
requestParameters.put(key, String.valueOf(value));
|
||||
|
||||
Reference in New Issue
Block a user