diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java
index 50ed88967..38700c064 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java
@@ -19,8 +19,8 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
+import org.apache.struts2.dispatcher.HttpParameters;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -198,9 +198,10 @@ public class ExceptionMappingInterceptor extends AbstractInterceptor {
List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e);
if (mappingConfig != null && mappingConfig.getResult()!=null) {
- Map parameterMap = mappingConfig.getParams();
+ Map mappingParams = mappingConfig.getParams();
// create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable
- invocation.getInvocationContext().setParameters(new HashMap(parameterMap));
+ HttpParameters parameters = HttpParameters.create(mappingParams).build();
+ invocation.getInvocationContext().setParameters(parameters);
result = mappingConfig.getResult();
publishException(invocation, new ExceptionHolder(e));
} else {
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java
index 186e42ec1..a758e45c6 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java
@@ -20,6 +20,8 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.Locale;
import java.util.Map;
@@ -166,7 +168,7 @@ public class I18nInterceptor extends AbstractInterceptor {
protected class LocaleFinder {
protected String storage = Storage.SESSION.toString();
- protected Object requestedLocale = null;
+ protected Parameter requestedLocale = null;
protected ActionInvocation actionInvocation = null;
@@ -177,7 +179,7 @@ public class I18nInterceptor extends AbstractInterceptor {
protected void find() {
//get requested locale
- Map params = actionInvocation.getInvocationContext().getParameters();
+ HttpParameters params = actionInvocation.getInvocationContext().getParameters();
storage = Storage.SESSION.toString();
@@ -259,13 +261,11 @@ public class I18nInterceptor extends AbstractInterceptor {
return locale;
}
- protected Object findLocaleParameter(Map params, String parameterName) {
- Object requestedLocale = params.remove(parameterName);
- if (requestedLocale != null && requestedLocale.getClass().isArray()
- && ((Object[]) requestedLocale).length > 0) {
- requestedLocale = ((Object[]) requestedLocale)[0];
-
- LOG.debug("Requested locale: {}", requestedLocale);
+ protected Parameter findLocaleParameter(HttpParameters params, String parameterName) {
+ Parameter requestedLocale = params.get(parameterName);
+ params.remove(parameterName);
+ if (requestedLocale.isDefined()) {
+ LOG.debug("Requested locale: {}", requestedLocale.getValue());
}
return requestedLocale;
}
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java
index d3c48a3e0..cac043688 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java
@@ -20,6 +20,7 @@ import com.opensymphony.xwork2.util.TextParseUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.Collection;
import java.util.HashSet;
@@ -107,12 +108,12 @@ public class ParameterFilterInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
- Map parameters = invocation.getInvocationContext().getParameters();
+ HttpParameters parameters = invocation.getInvocationContext().getParameters();
HashSet paramsToRemove = new HashSet<>();
Map includesExcludesMap = getIncludesExcludesMap();
- for (String param : parameters.keySet()) {
+ for (String param : parameters.getNames()) {
boolean currentAllowed = !isDefaultBlock();
for (String currRule : includesExcludesMap.keySet()) {
@@ -129,9 +130,7 @@ public class ParameterFilterInterceptor extends AbstractInterceptor {
LOG.debug("Params to remove: {}", paramsToRemove);
- for (Object aParamsToRemove : paramsToRemove) {
- parameters.remove(aParamsToRemove);
- }
+ parameters.remove(paramsToRemove);
return invocation.invoke();
}
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java
index 68bb1547a..6155c61f1 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java
@@ -20,9 +20,10 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.TextParseUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.Collections;
-import java.util.Map;
import java.util.Set;
/**
@@ -98,22 +99,17 @@ public class ParameterRemoverInterceptor extends AbstractInterceptor {
if (!(invocation.getAction() instanceof NoParameters)
&& (null != this.paramNames)) {
ActionContext ac = invocation.getInvocationContext();
- final Map parameters = ac.getParameters();
+ HttpParameters parameters = ac.getParameters();
if (parameters != null) {
for (String removeName : paramNames) {
- // see if the field is in the parameter map
- if (parameters.containsKey(removeName)) {
-
- try {
- String[] values = (String[]) parameters.get(removeName);
- String value = values[0];
- if (null != value && this.paramValues.contains(value)) {
- parameters.remove(removeName);
- }
- } catch (Exception e) {
- LOG.error("Failed to convert parameter to string", e);
+ try {
+ Parameter parameter = parameters.get(removeName);
+ if (parameter.isDefined() && this.paramValues.contains(parameter.getValue())) {
+ parameters.remove(removeName);
}
+ } catch (Exception e) {
+ LOG.error("Failed to convert parameter to string", e);
}
}
}
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java
index 52f4f369e..67288ffb3 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java
@@ -18,8 +18,6 @@ package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.XWorkConstants;
-import com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler;
-import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
@@ -28,6 +26,8 @@ import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.Collection;
import java.util.Comparator;
@@ -108,7 +108,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
Object action = invocation.getAction();
if (!(action instanceof NoParameters)) {
ActionContext ac = invocation.getInvocationContext();
- final Map parameters = retrieveParameters(ac);
+ HttpParameters parameters = retrieveParameters(ac);
if (LOG.isDebugEnabled()) {
LOG.debug("Setting params {}", getParameterLogMap(parameters));
@@ -139,7 +139,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
* @param ac The action context
* @return The parameter map to apply
*/
- protected Map retrieveParameters(ActionContext ac) {
+ protected HttpParameters retrieveParameters(ActionContext ac) {
return ac.getParameters();
}
@@ -154,26 +154,24 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
* In subclasses both retrieveParameters() and addParametersToContext() should be overridden.
*
*/
- protected void addParametersToContext(ActionContext ac, Map newParams) {
+ protected void addParametersToContext(ActionContext ac, Map newParams) {
}
- protected void setParameters(final Object action, ValueStack stack, final Map parameters) {
- Map params;
- Map acceptableParameters;
+ protected void setParameters(final Object action, ValueStack stack, HttpParameters parameters) {
+ HttpParameters params;
+ Map acceptableParameters;
if (ordered) {
- params = new TreeMap<>(getOrderedComparator());
+ params = HttpParameters.createEmpty().withComparator(getOrderedComparator()).withParent(parameters).build();
acceptableParameters = new TreeMap<>(getOrderedComparator());
- params.putAll(parameters);
} else {
- params = new TreeMap<>(parameters);
+ params = HttpParameters.createEmpty().withParent(parameters).build();
acceptableParameters = new TreeMap<>();
}
- for (Map.Entry entry : params.entrySet()) {
- String name = entry.getKey();
- Object value = entry.getValue();
- if (isAcceptableParameter(name, action) && isAcceptableValue(value)) {
- acceptableParameters.put(name, entry.getValue());
+ for (String name : params.getNames()) {
+ Parameter parameter = params.get(name);
+ if (isAcceptableParameter(name, action) && isAcceptableValue(parameter.getValue())) {
+ acceptableParameters.put(name, parameter);
}
}
@@ -201,11 +199,11 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
accessValueStack.setExcludeProperties(excludedPatterns.getExcludedPatterns());
}
- for (Map.Entry entry : acceptableParameters.entrySet()) {
+ for (Map.Entry entry : acceptableParameters.entrySet()) {
String name = entry.getKey();
- Object value = entry.getValue();
+ Parameter value = entry.getValue();
try {
- newStack.setParameter(name, value);
+ newStack.setParameter(name, value.getValue());
} catch (RuntimeException e) {
if (devMode) {
notifyDeveloperParameterException(action, name, e.getMessage());
@@ -285,30 +283,16 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
return rbCollator;
}
- protected String getParameterLogMap(Map parameters) {
+ protected String getParameterLogMap(HttpParameters parameters) {
if (parameters == null) {
return "NONE";
}
StringBuilder logEntry = new StringBuilder();
- for (Map.Entry entry : parameters.entrySet()) {
- logEntry.append(String.valueOf(entry.getKey()));
+ for (String name : parameters.getNames()) {
+ logEntry.append(String.valueOf(name));
logEntry.append(" => ");
- if (entry.getValue() instanceof Object[]) {
- Object[] valueArray = (Object[]) entry.getValue();
- logEntry.append("[ ");
- if (valueArray.length > 0 ) {
- for (int indexA = 0; indexA < (valueArray.length - 1); indexA++) {
- Object valueAtIndex = valueArray[indexA];
- logEntry.append(String.valueOf(valueAtIndex));
- logEntry.append(", ");
- }
- logEntry.append(String.valueOf(valueArray[valueArray.length - 1]));
- }
- logEntry.append(" ] ");
- } else {
- logEntry.append(String.valueOf(entry.getValue()));
- }
+ logEntry.append(parameters.get(name).getValue());
}
return logEntry.toString();
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
index 914a2a12e..07a5a9bb2 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
@@ -21,15 +21,19 @@ import com.opensymphony.xwork2.XWorkConstants;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.Parameterizable;
import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.*;
+import com.opensymphony.xwork2.util.ClearableValueStack;
+import com.opensymphony.xwork2.util.LocalizedTextUtil;
+import com.opensymphony.xwork2.util.TextParseUtil;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.Collections;
import java.util.Map;
-import java.util.TreeMap;
/**
@@ -212,28 +216,24 @@ public class StaticParametersInterceptor extends AbstractInterceptor {
* @param newParams The parameter map to apply
*/
protected void addParametersToContext(ActionContext ac, Map newParams) {
- Map previousParams = ac.getParameters();
+ HttpParameters previousParams = ac.getParameters();
- Map combinedParams;
- if ( overwrite ) {
+ HttpParameters.Builder combinedParams = HttpParameters.createEmpty();
+ if (overwrite) {
if (previousParams != null) {
- combinedParams = new TreeMap<>(previousParams);
- } else {
- combinedParams = new TreeMap<>();
+ combinedParams = combinedParams.withParent(previousParams);
}
- if ( newParams != null) {
- combinedParams.putAll(newParams);
+ if (newParams != null) {
+ combinedParams = combinedParams.withExtraParams(newParams);
}
} else {
if (newParams != null) {
- combinedParams = new TreeMap<>(newParams);
- } else {
- combinedParams = new TreeMap<>();
+ combinedParams = combinedParams.withExtraParams(newParams);
}
- if ( previousParams != null) {
- combinedParams.putAll(previousParams);
+ if (previousParams != null) {
+ combinedParams = combinedParams.withParent(previousParams);
}
}
- ac.setParameters(combinedParams);
+ ac.setParameters(combinedParams.build());
}
}
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
index 327d2c6db..d65ebecfc 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
@@ -8,12 +8,12 @@ import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor;
import com.opensymphony.xwork2.interceptor.ParametersInterceptor;
import com.opensymphony.xwork2.util.AnnotationUtils;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
/**
* Annotation based version of {@link ParameterFilterInterceptor}.
@@ -38,7 +38,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor {
@Override public String intercept(ActionInvocation invocation) throws Exception {
final Object action = invocation.getAction();
- Map parameters = invocation.getInvocationContext().getParameters();
+ HttpParameters parameters = invocation.getInvocationContext().getParameters();
Object model = invocation.getStack().peek();
if (model == action) {
@@ -55,7 +55,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor {
AnnotationUtils.addAllFields(Allowed.class, model.getClass(), annotatedFields);
}
- for (String paramName : parameters.keySet()) {
+ for (String paramName : parameters.getNames()) {
boolean allowed = false;
for (Field field : annotatedFields) {
@@ -77,7 +77,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor {
AnnotationUtils.addAllFields(Blocked.class, model.getClass(), annotatedFields);
}
- for (String paramName : parameters.keySet()) {
+ for (String paramName : parameters.getNames()) {
for (Field field : annotatedFields) {
//TODO only matches exact field names. need to change to it matches start of ognl expression
//i.e take param name up to first . (period) and match against that
@@ -88,9 +88,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor {
}
}
- for (String aParamsToRemove : paramsToRemove) {
- parameters.remove(aParamsToRemove);
- }
+ parameters.remove(paramsToRemove);
return invocation.invoke();
}
diff --git a/core/src/main/java/org/apache/struts2/components/ActionComponent.java b/core/src/main/java/org/apache/struts2/components/ActionComponent.java
index 3e98f6ca5..762aafdbf 100644
--- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java
+++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java
@@ -35,6 +35,7 @@ import org.apache.struts2.StrutsException;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.RequestMap;
+import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.views.annotations.StrutsTag;
@@ -178,7 +179,7 @@ public class ActionComponent extends ContextBean {
}
protected Map createExtraContext() {
- Map newParams = createParametersForContext();
+ HttpParameters newParams = createParametersForContext();
ActionContext ctx = new ActionContext(stack.getContext());
PageContext pageContext = (PageContext) ctx.get(ServletActionContext.PAGE_CONTEXT);
@@ -208,16 +209,17 @@ public class ActionComponent extends ContextBean {
*
* @return A map of String[] parameters
*/
- protected Map createParametersForContext() {
- Map parentParams = null;
+ protected HttpParameters createParametersForContext() {
+ HttpParameters parentParams = null;
if (!ignoreContextParams) {
parentParams = new ActionContext(getStack().getContext()).getParameters();
}
- Map newParams = (parentParams != null)
- ? new HashMap(parentParams)
- : new HashMap();
+ HttpParameters.Builder builder = HttpParameters.createEmpty();
+ if (parentParams != null) {
+ builder = builder.withParent(parentParams);
+ }
if (parameters != null) {
Map params = new HashMap<>();
@@ -231,9 +233,9 @@ public class ActionComponent extends ContextBean {
params.put(key, new String[]{val.toString()});
}
}
- newParams.putAll(params);
+ builder = builder.withExtraParams(params);
}
- return newParams;
+ return builder.build();
}
public ActionProxy getProxy() {
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
index 93d38a429..9f6026747 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
@@ -607,7 +607,7 @@ public class Dispatcher {
Map requestMap = new RequestMap(request);
// parameters map wrapping the http parameters. ActionMapping parameters are now handled and applied separately
- Map params = new HashMap(request.getParameterMap());
+ HttpParameters params = HttpParameters.create(request.getParameterMap()).build();
// session map wrapping the http session
Map session = new SessionMap(request);
@@ -628,7 +628,7 @@ public class Dispatcher {
* Action context.
*
* @param requestMap a Map of all request attributes.
- * @param parameterMap a Map of all request parameters.
+ * @param parameters an Object of all request parameters.
* @param sessionMap a Map of all session attributes.
* @param applicationMap a Map of all servlet context attributes.
* @param request the HttpServletRequest object.
@@ -638,13 +638,13 @@ public class Dispatcher {
* @since 2.3.17
*/
public HashMap createContextMap(Map requestMap,
- Map parameterMap,
+ HttpParameters parameters,
Map sessionMap,
Map applicationMap,
HttpServletRequest request,
HttpServletResponse response) {
HashMap extraContext = new HashMap<>();
- extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));
+ extraContext.put(ActionContext.PARAMETERS, parameters);
extraContext.put(ActionContext.SESSION, sessionMap);
extraContext.put(ActionContext.APPLICATION, applicationMap);
@@ -665,7 +665,7 @@ public class Dispatcher {
extraContext.put("request", requestMap);
extraContext.put("session", sessionMap);
extraContext.put("application", applicationMap);
- extraContext.put("parameters", parameterMap);
+ extraContext.put("parameters", parameters);
AttributeMap attrMap = new AttributeMap(extraContext);
extraContext.put("attr", attrMap);
diff --git a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java
index 93f527bfe..01dec1678 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java
@@ -24,11 +24,10 @@ package org.apache.struts2.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.interceptor.ParametersInterceptor;
import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
-import java.util.Collections;
import java.util.Map;
-import java.util.TreeMap;
/**
*
@@ -82,12 +81,12 @@ public class ActionMappingParametersInteceptor extends ParametersInterceptor {
* @return the parameters from the action mapping in the context. If none found, returns an empty map.
*/
@Override
- protected Map retrieveParameters(ActionContext ac) {
+ protected HttpParameters retrieveParameters(ActionContext ac) {
ActionMapping mapping = (ActionMapping) ac.get(ServletActionContext.ACTION_MAPPING);
if (mapping != null) {
- return mapping.getParams();
+ return HttpParameters.create(mapping.getParams()).build();
} else {
- return Collections.emptyMap();
+ return HttpParameters.createEmpty().build();
}
}
@@ -102,16 +101,10 @@ public class ActionMappingParametersInteceptor extends ParametersInterceptor {
*
*/
@Override
- protected void addParametersToContext(ActionContext ac, Map newParams) {
- Map previousParams = ac.getParameters();
- Map combinedParams;
- if (previousParams != null) {
- combinedParams = new TreeMap(previousParams);
- } else {
- combinedParams = new TreeMap();
- }
- combinedParams.putAll(newParams);
+ protected void addParametersToContext(ActionContext ac, Map newParams) {
+ HttpParameters previousParams = ac.getParameters();
+ HttpParameters.Builder combinedParams = HttpParameters.createEmpty().withParent(previousParams).withExtraParams(newParams);
- ac.setParameters(combinedParams);
+ ac.setParameters(combinedParams.build());
}
}
diff --git a/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java
index bad1c2529..f6eded530 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java
@@ -25,11 +25,11 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
/**
*
@@ -60,33 +60,30 @@ public class CheckboxInterceptor extends AbstractInterceptor {
private static final Logger LOG = LogManager.getLogger(CheckboxInterceptor.class);
public String intercept(ActionInvocation ai) throws Exception {
- Map parameters = ai.getInvocationContext().getParameters();
- Map newParams = new HashMap<>();
- Set> entries = parameters.entrySet();
+ HttpParameters parameters = ai.getInvocationContext().getParameters();
+ Map extraParams = new HashMap<>();
- for (Iterator> iterator = entries.iterator(); iterator.hasNext();) {
- Map.Entry entry = iterator.next();
- String key = entry.getKey();
+ for (String name : parameters.getNames()) {
+ if (name.startsWith("__checkbox_")) {
+ String checkboxName = name.substring("__checkbox_".length());
- if (key.startsWith("__checkbox_")) {
- String name = key.substring("__checkbox_".length());
-
- Object values = entry.getValue();
- iterator.remove();
- if (values != null && values instanceof String[] && ((String[])values).length > 1) {
+ Parameter value = parameters.get(checkboxName);
+ parameters = parameters.remove(name);
+ if (value.isMultiple()) {
LOG.debug("Bypassing automatic checkbox detection due to multiple checkboxes of the same name: {}", name);
continue;
}
// is this checkbox checked/submitted?
- if (!parameters.containsKey(name)) {
+ if (!parameters.contains(name)) {
// if not, let's be sure to default the value to false
- newParams.put(name, new String[]{uncheckedValue});
+ extraParams.put(name, new String[]{uncheckedValue});
}
}
}
- parameters.putAll(newParams);
+
+ ai.getInvocationContext().setParameters(parameters.clone(extraParams));
return ai.invoke();
}
diff --git a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
index 05d38514a..e4ccd6c43 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
@@ -4,6 +4,8 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -62,33 +64,30 @@ public class DateTextFieldInterceptor implements Interceptor {
}
public String intercept(ActionInvocation ai) throws Exception {
- Map parameters = ai.getInvocationContext().getParameters();
- Set> entries = parameters.entrySet();
+ HttpParameters parameters = ai.getInvocationContext().getParameters();
Map> dates = new HashMap<>();
DateWord[] dateWords = DateWord.getAll();
// Get all the values of date type
- for (Iterator> iterator = entries.iterator(); iterator.hasNext();) {
- Entry entry = iterator.next();
- String key = entry.getKey();
+ for (String name : parameters.getNames()) {
for (DateWord dateWord : dateWords) {
String dateKey = "__" + dateWord.getDescription() + "_";
- if (key.startsWith(dateKey)) {
- String name = key.substring(dateKey.length());
+ if (name.startsWith(dateKey)) {
+ String key = name.substring(dateKey.length());
- if (entry.getValue() instanceof String[]) {
- String[] values = (String[])entry.getValue();
- if (values.length > 0 && !"".equals(values[0])) {
- iterator.remove();
- Map map = dates.get(name);
- if (map == null) {
- map = new HashMap<>();
- dates.put(name, map);
- }
- map.put(dateWord.getDateType(), values[0]);
- }
+ Parameter param = parameters.get(key);
+
+ if (param.isDefined()) {
+ Map map = dates.get(name);
+ if (map == null) {
+ map = new HashMap<>();
+ dates.put(name, map);
+ }
+ map.put(dateWord.getDateType(), param.getValue());
+
+ parameters = parameters.remove(name);
}
break;
}
@@ -115,7 +114,8 @@ public class DateTextFieldInterceptor implements Interceptor {
LOG.warn("Cannot parse the parameter '{}' with format '{}' and with value '{}'", dateEntry.getKey(), dateFormat, dateValue);
}
}
- parameters.putAll(newParams);
+
+ ai.getInvocationContext().setParameters(parameters.clone(newParams));
return ai.invoke();
}
diff --git a/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
index 15bbabeb4..0ceacc4a4 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
@@ -294,11 +294,11 @@ public class FileUploadInterceptor extends AbstractInterceptor {
}
if (!acceptedFiles.isEmpty()) {
- Map params = ac.getParameters();
-
- params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]));
- params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]));
- params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]));
+ Map newParams = new HashMap<>();
+ newParams.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]));
+ newParams.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]));
+ newParams.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]));
+ ac.setParameters(ac.getParameters().clone(newParams));
}
}
} else {
diff --git a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
index d250a8f61..a5c67f2aa 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
@@ -24,6 +24,7 @@ import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsStatics;
+import org.apache.struts2.dispatcher.HttpParameters;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
@@ -87,7 +88,7 @@ public class I18nInterceptor extends com.opensymphony.xwork2.interceptor.I18nInt
@Override
protected void find() {
//get requested locale
- Map params = actionInvocation.getInvocationContext().getParameters();
+ HttpParameters params = actionInvocation.getInvocationContext().getParameters();
storage = Storage.SESSION.toString();
requestedLocale = findLocaleParameter(params, parameterName);
diff --git a/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java
index 4c8b84459..337fd0caa 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java
@@ -22,11 +22,10 @@ package org.apache.struts2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
/**
* Just as the CheckboxInterceptor checks that if only the hidden field is present, so too does this interceptor. If
@@ -41,36 +40,32 @@ public class MultiselectInterceptor extends AbstractInterceptor {
* If the "__multiselect_" request parameter is present and its visible counterpart is not, set a new request parameter
* to an empty Sting.
*
- * @param actionInvocation ActionInvocation
+ * @param ai ActionInvocation
* @return the result of the action
* @throws Exception if error
* @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
*/
- public String intercept(ActionInvocation actionInvocation) throws Exception {
- Map parameters = actionInvocation.getInvocationContext().getParameters();
+ public String intercept(ActionInvocation ai) throws Exception {
+ HttpParameters parameters = ai.getInvocationContext().getParameters();
Map newParams = new HashMap<>();
- Set keys = parameters.keySet();
- for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
- String key = iterator.next();
-
- if (key.startsWith("__multiselect_")) {
- String name = key.substring("__multiselect_".length());
-
- iterator.remove();
+ for (String name : parameters.getNames()) {
+ if (name.startsWith("__multiselect_")) {
+ String key = name.substring("__multiselect_".length());
// is this multi-select box submitted?
- if (!parameters.containsKey(name)) {
-
+ if (!parameters.contains(key)) {
// if not, let's be sure to default the value to an empty string array
- newParams.put(name, new String[0]);
+ newParams.put(key, new String[0]);
}
+
+ parameters = parameters.remove(name);
}
}
- parameters.putAll(newParams);
+ ai.getInvocationContext().setParameters(parameters.clone(newParams));
- return actionInvocation.invoke();
+ return ai.invoke();
}
-}
\ No newline at end of file
+}
diff --git a/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
index 4ad443117..4a6874401 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
@@ -26,13 +26,13 @@ import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.util.InvocationSessionStore;
import org.apache.struts2.util.TokenHelper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import java.util.Map;
/**
@@ -126,7 +126,7 @@ public class TokenSessionStoreInterceptor extends TokenInterceptor {
String token = TokenHelper.getToken(tokenName);
if ((tokenName != null) && (token != null)) {
- Map params = ac.getParameters();
+ HttpParameters params = ac.getParameters();
params.remove(tokenName);
params.remove(TokenHelper.TOKEN_NAME_FIELD);
diff --git a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
index 296d4105f..2e9efdddf 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
@@ -32,6 +32,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.dispatcher.Parameter;
import org.apache.struts2.dispatcher.PrepareOperations;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.freemarker.FreemarkerResult;
@@ -269,11 +270,8 @@ public class DebuggingInterceptor extends AbstractInterceptor {
* @return The parameter value
*/
private String getParameter(String key) {
- String[] arr = (String[]) ActionContext.getContext().getParameters().get(key);
- if (arr != null && arr.length > 0) {
- return arr[0];
- }
- return null;
+ Parameter parameter = ActionContext.getContext().getParameters().get(key);
+ return parameter.getValue();
}
/**
diff --git a/core/src/main/java/org/apache/struts2/util/TokenHelper.java b/core/src/main/java/org/apache/struts2/util/TokenHelper.java
index d6e042ef7..d4ae8aa5f 100644
--- a/core/src/main/java/org/apache/struts2/util/TokenHelper.java
+++ b/core/src/main/java/org/apache/struts2/util/TokenHelper.java
@@ -25,6 +25,8 @@ import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.dispatcher.HttpParameters;
import java.math.BigInteger;
import java.security.SecureRandom;
@@ -128,17 +130,14 @@ public class TokenHelper {
if (tokenName == null ) {
return null;
}
- Map params = ActionContext.getContext().getParameters();
- String[] tokens = (String[]) params.get(tokenName);
- String token;
+ HttpParameters params = ActionContext.getContext().getParameters();
+ Parameter parameter = params.get(tokenName);
- if ((tokens == null) || (tokens.length < 1)) {
+ if (!parameter.isDefined()) {
LOG.warn("Could not find token mapped to token name: {}", tokenName);
return null;
}
-
- token = tokens[0];
- return token;
+ return parameter.getValue();
}
/**
@@ -147,23 +146,19 @@ public class TokenHelper {
* @return the token name found in the params, or null if it could not be found
*/
public static String getTokenName() {
- Map params = ActionContext.getContext().getParameters();
+ HttpParameters params = ActionContext.getContext().getParameters();
- if (!params.containsKey(TOKEN_NAME_FIELD)) {
+ if (!params.contains(TOKEN_NAME_FIELD)) {
LOG.warn("Could not find token name in params.");
return null;
}
- String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);
- String tokenName;
-
- if ((tokenNames == null) || (tokenNames.length < 1)) {
+ Parameter parameter = params.get(TOKEN_NAME_FIELD);
+ if (!parameter.isDefined()) {
LOG.warn("Got a null or empty token name.");
return null;
}
-
- tokenName = tokenNames[0];
- return tokenName;
+ return parameter.getValue();
}
/**
diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java b/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java
index ab7abea1f..1a14d662f 100644
--- a/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java
+++ b/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java
@@ -30,6 +30,7 @@ import org.apache.struts2.RequestUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.ApplicationMap;
import org.apache.struts2.dispatcher.Dispatcher;
+import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.dispatcher.RequestMap;
import org.apache.struts2.dispatcher.SessionMap;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
@@ -60,8 +61,11 @@ public class TagUtils {
"has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag.");
}
stack = du.getContainer().getInstance(ValueStackFactory.class).createValueStack();
+
+ HttpParameters params = HttpParameters.create(req.getParameterMap()).build();
+
Map extraContext = du.createContextMap(new RequestMap(req),
- req.getParameterMap(),
+ params,
new SessionMap(req),
new ApplicationMap(pageContext.getServletContext()),
req,