diff --git a/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java b/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java index ac132e4ea..50fda1c94 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java @@ -71,11 +71,13 @@ public class HttpParameters implements Cloneable { Object value = entry.getValue(); if (value != null && value.getClass().isArray()) { Object[] values = (Object[]) value; - Set strValues = new TreeSet<>(); + String[] strValues = new String[values.length]; + int i = 0; for (Object v : values) { - strValues.add(String.valueOf(v)); + strValues[i] = String.valueOf(v); + i++; } - result.put(entry.getKey(), strValues.toArray(new String[strValues.size()])); + result.put(entry.getKey(), strValues); } else if (value != null) { result.put(entry.getKey(), new String[]{String.valueOf(value)}); } 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 f6eded530..2bb49aa75 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java @@ -67,7 +67,7 @@ public class CheckboxInterceptor extends AbstractInterceptor { if (name.startsWith("__checkbox_")) { String checkboxName = name.substring("__checkbox_".length()); - Parameter value = parameters.get(checkboxName); + Parameter value = parameters.get(name); parameters = parameters.remove(name); if (value.isMultiple()) { LOG.debug("Bypassing automatic checkbox detection due to multiple checkboxes of the same name: {}", name); @@ -75,9 +75,9 @@ public class CheckboxInterceptor extends AbstractInterceptor { } // is this checkbox checked/submitted? - if (!parameters.contains(name)) { + if (!parameters.contains(checkboxName)) { // if not, let's be sure to default the value to false - extraParams.put(name, new String[]{uncheckedValue}); + extraParams.put(checkboxName, new String[]{ uncheckedValue }); } } } diff --git a/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java index 48647adf5..c7f201031 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java @@ -24,10 +24,12 @@ package org.apache.struts2.interceptor; import java.util.HashMap; import java.util.Map; +import com.opensymphony.xwork2.ActionInvocation; import org.apache.struts2.StrutsInternalTestCase; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.mock.MockActionInvocation; +import org.apache.struts2.dispatcher.HttpParameters; /** * Unit test for ChecboxInterceptor. @@ -40,15 +42,20 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { protected void setUp() throws Exception { super.setUp(); - param = new HashMap(); + param = new HashMap<>(); interceptor = new CheckboxInterceptor(); ai = new MockActionInvocation(); ai.setInvocationContext(ActionContext.getContext()); - ActionContext.getContext().setParameters(param); } - + + private void prepare(ActionInvocation ai) { + ai.getInvocationContext().setParameters(HttpParameters.create(param).build()); + } + public void testNoParam() throws Exception { + prepare(ai); + interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); @@ -58,21 +65,27 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { public void testPassthroughOne() throws Exception { param.put("user", "batman"); + + prepare(ai); + interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - assertEquals(1, param.size()); + assertEquals(1, ai.getInvocationContext().getParameters().getNames().size()); } public void testPassthroughTwo() throws Exception { param.put("user", "batman"); param.put("email", "batman@comic.org"); + + prepare(ai); + interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - assertEquals(2, param.size()); + assertEquals(2, ai.getInvocationContext().getParameters().getNames().size()); } public void testOneCheckboxTrue() throws Exception { @@ -82,13 +95,16 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { param.put("__checkbox_superpower", "true"); assertTrue(param.containsKey("__checkbox_superpower")); + prepare(ai); + interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - - assertFalse(param.containsKey("__checkbox_superpower")); - assertEquals(3, param.size()); // should be 3 as __checkbox_ should be removed - assertEquals("true", param.get("superpower")); + + HttpParameters parameters = ai.getInvocationContext().getParameters(); + assertFalse(parameters.contains("__checkbox_superpower")); + assertEquals(3, parameters.getNames().size()); // should be 3 as __checkbox_ should be removed + assertEquals("true", parameters.get("superpower").getValue()); } public void testOneCheckboxNoValue() throws Exception { @@ -97,13 +113,16 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { param.put("__checkbox_superpower", "false"); assertTrue(param.containsKey("__checkbox_superpower")); + prepare(ai); + interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - - assertFalse(param.containsKey("__checkbox_superpower")); - assertEquals(3, param.size()); // should be 3 as __checkbox_ should be removed - assertEquals("false", ((String[])param.get("superpower"))[0]); + + HttpParameters parameters = ai.getInvocationContext().getParameters(); + assertFalse(parameters.contains("__checkbox_superpower")); + assertEquals(3, parameters.getNames().size()); // should be 3 as __checkbox_ should be removed + assertEquals("false", parameters.get("superpower").getValue()); } public void testOneCheckboxNoValueDifferentDefault() throws Exception { @@ -112,28 +131,34 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { param.put("__checkbox_superpower", "false"); assertTrue(param.containsKey("__checkbox_superpower")); + prepare(ai); + interceptor.setUncheckedValue("off"); interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - - assertFalse(param.containsKey("__checkbox_superpower")); - assertEquals(3, param.size()); // should be 3 as __checkbox_ should be removed - assertEquals("off", ((String[])param.get("superpower"))[0]); + + HttpParameters parameters = ai.getInvocationContext().getParameters(); + assertFalse(parameters.contains("__checkbox_superpower")); + assertEquals(3, parameters.getNames().size()); // should be 3 as __checkbox_ should be removed + assertEquals("off", parameters.get("superpower").getValue()); } public void testTwoCheckboxNoValue() throws Exception { param.put("user", "batman"); param.put("email", "batman@comic.org"); - param.put("__checkbox_superpower", new String[]{"true","true"}); + param.put("__checkbox_superpower", new String[]{"true", "true"}); + + prepare(ai); interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - assertFalse(param.containsKey("__checkbox_superpower")); - assertEquals(2, param.size()); // should be 2 as __checkbox_ should be removed - assertNull(param.get("superpower")); + HttpParameters parameters = ai.getInvocationContext().getParameters(); + assertFalse(parameters.contains("__checkbox_superpower")); + assertEquals(2, parameters.getNames().size()); // should be 2 as __checkbox_ should be removed + assertFalse(parameters.get("superpower").isDefined()); } public void testTwoCheckboxMixed() throws Exception { @@ -145,15 +170,18 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { assertTrue(param.containsKey("__checkbox_superpower")); assertTrue(param.containsKey("__checkbox_cool")); + prepare(ai); + interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - - assertFalse(param.containsKey("__checkbox_superpower")); - assertFalse(param.containsKey("__checkbox_cool")); - assertEquals(4, param.size()); // should be 4 as __checkbox_ should be removed - assertEquals("yes", param.get("superpower")); - assertEquals("false", ((String[])param.get("cool"))[0]); // will use false as default and not 'no' + + HttpParameters parameters = ai.getInvocationContext().getParameters(); + assertFalse(parameters.contains("__checkbox_superpower")); + assertFalse(parameters.contains("__checkbox_cool")); + assertEquals(4, parameters.getNames().size()); // should be 4 as __checkbox_ should be removed + assertEquals("yes", parameters.get("superpower").getValue()); + assertEquals("false", parameters.get("cool").getValue()); // will use false as default and not 'no' } public void testTwoCheckboxMixedWithDifferentDefault() throws Exception { @@ -165,16 +193,19 @@ public class CheckboxInterceptorTest extends StrutsInternalTestCase { assertTrue(param.containsKey("__checkbox_superpower")); assertTrue(param.containsKey("__checkbox_cool")); + prepare(ai); + interceptor.setUncheckedValue("no"); interceptor.init(); interceptor.intercept(ai); interceptor.destroy(); - - assertFalse(param.containsKey("__checkbox_superpower")); - assertFalse(param.containsKey("__checkbox_cool")); - assertEquals(4, param.size()); // should be 4 as __checkbox_ should be removed - assertEquals("yes", param.get("superpower")); - assertEquals("no", ((String[])param.get("cool"))[0]); + + HttpParameters parameters = ai.getInvocationContext().getParameters(); + assertFalse(parameters.contains("__checkbox_superpower")); + assertFalse(parameters.contains("__checkbox_cool")); + assertEquals(4, parameters.getNames().size()); // should be 4 as __checkbox_ should be removed + assertEquals("yes", parameters.get("superpower").getValue()); + assertEquals("no", parameters.get("cool").getValue()); } }