mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
Merge pull request #630 from apache/WW-4514-url
[WW-4514] Fixes building query string with empty parameters
This commit is contained in:
+3
@@ -118,6 +118,8 @@ import org.apache.struts2.conversion.StrutsTypeConverterCreator;
|
||||
import org.apache.struts2.conversion.StrutsTypeConverterHolder;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
import org.apache.struts2.url.ParametersStringBuilder;
|
||||
import org.apache.struts2.url.StrutsParametersStringBuilder;
|
||||
import org.apache.struts2.url.StrutsUrlDecoder;
|
||||
import org.apache.struts2.url.StrutsUrlEncoder;
|
||||
import org.apache.struts2.url.UrlDecoder;
|
||||
@@ -234,6 +236,7 @@ public class StrutsDefaultConfigurationProvider implements ConfigurationProvider
|
||||
|
||||
.factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON)
|
||||
|
||||
.factory(ParametersStringBuilder.class, StrutsParametersStringBuilder.class, Scope.SINGLETON)
|
||||
.factory(UrlEncoder.class, StrutsUrlEncoder.class, Scope.SINGLETON)
|
||||
.factory(UrlDecoder.class, StrutsUrlDecoder.class, Scope.SINGLETON)
|
||||
;
|
||||
|
||||
@@ -458,6 +458,7 @@ public final class StrutsConstants {
|
||||
/** See {@link org.apache.struts2.components.Date#setDateFormatter(DateFormatter)} */
|
||||
public static final String STRUTS_DATE_FORMATTER = "struts.date.formatter";
|
||||
|
||||
public static final String STRUTS_URL_PARAMETERS_STRING_BUILDER = "struts.url.parametersStringBuilder";
|
||||
public static final String STRUTS_URL_ENCODER = "struts.url.encoder";
|
||||
public static final String STRUTS_URL_DECODER = "struts.url.decoder";
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ import org.apache.struts2.dispatcher.DispatcherErrorHandler;
|
||||
import org.apache.struts2.dispatcher.StaticContentLoader;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
|
||||
import org.apache.struts2.url.ParametersStringBuilder;
|
||||
import org.apache.struts2.url.UrlDecoder;
|
||||
import org.apache.struts2.url.UrlEncoder;
|
||||
import org.apache.struts2.util.ContentTypeMatcher;
|
||||
@@ -431,6 +432,7 @@ public class StrutsBeanSelectionProvider extends AbstractBeanSelectionProvider {
|
||||
alias(ExpressionCacheFactory.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_CACHE_FACTORY, builder, props, Scope.SINGLETON);
|
||||
alias(BeanInfoCacheFactory.class, StrutsConstants.STRUTS_OGNL_BEANINFO_CACHE_FACTORY, builder, props, Scope.SINGLETON);
|
||||
|
||||
alias(ParametersStringBuilder.class, StrutsConstants.STRUTS_URL_PARAMETERS_STRING_BUILDER, builder, props, Scope.SINGLETON);
|
||||
alias(UrlEncoder.class, StrutsConstants.STRUTS_URL_ENCODER, builder, props, Scope.SINGLETON);
|
||||
alias(UrlDecoder.class, StrutsConstants.STRUTS_URL_DECODER, builder, props, Scope.SINGLETON);
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.url;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A builder used to create a proper query string out of a set of parameters
|
||||
* @since Struts 6.1.0
|
||||
*/
|
||||
public interface ParametersStringBuilder {
|
||||
|
||||
void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.url;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class StrutsParametersStringBuilder implements ParametersStringBuilder {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(StrutsParametersStringBuilder.class);
|
||||
|
||||
private final UrlEncoder encoder;
|
||||
|
||||
@Inject
|
||||
public StrutsParametersStringBuilder(UrlEncoder encoder) {
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator) {
|
||||
if ((params != null) && (params.size() > 0)) {
|
||||
LOG.debug("Building query string out of: {} parameters", params.size());
|
||||
StringBuilder queryString = new StringBuilder();
|
||||
|
||||
// Set params
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (value instanceof Iterable) {
|
||||
for (Object o : (Iterable<?>) value) {
|
||||
appendParameterSubstring(queryString, paramSeparator, name, o);
|
||||
}
|
||||
} else if (value instanceof Object[]) {
|
||||
Object[] array = (Object[]) value;
|
||||
for (Object o : array) {
|
||||
appendParameterSubstring(queryString, paramSeparator, name, o);
|
||||
}
|
||||
} else {
|
||||
appendParameterSubstring(queryString, paramSeparator, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (queryString.length() > 0) {
|
||||
if (!link.toString().contains("?")) {
|
||||
link.append("?");
|
||||
} else {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
link.append(queryString);
|
||||
}
|
||||
} else {
|
||||
LOG.debug("Params are empty, skipping building the query string");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendParameterSubstring(StringBuilder queryString, String paramSeparator, String name, Object value) {
|
||||
if (queryString.length() > 0) {
|
||||
queryString.append(paramSeparator);
|
||||
}
|
||||
|
||||
String encodedName = encoder.encode(name);
|
||||
queryString.append(encodedName);
|
||||
|
||||
queryString.append('=');
|
||||
if (value != null) {
|
||||
String encodedValue = encoder.encode(value.toString());
|
||||
queryString.append(encodedValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.url.ParametersStringBuilder;
|
||||
import org.apache.struts2.url.UrlDecoder;
|
||||
import org.apache.struts2.url.UrlEncoder;
|
||||
|
||||
@@ -31,7 +32,6 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -49,6 +49,7 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
private int httpPort = DEFAULT_HTTP_PORT;
|
||||
private int httpsPort = DEFAULT_HTTPS_PORT;
|
||||
|
||||
private ParametersStringBuilder parametersStringBuilder;
|
||||
private UrlEncoder encoder;
|
||||
private UrlDecoder decoder;
|
||||
|
||||
@@ -72,6 +73,11 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
this.decoder = decoder;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setParametersStringBuilder(ParametersStringBuilder builder) {
|
||||
this.parametersStringBuilder = builder;
|
||||
}
|
||||
|
||||
public String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map<String, Object> params) {
|
||||
return buildUrl(action, request, response, params, null, true, true);
|
||||
}
|
||||
@@ -170,9 +176,9 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
|
||||
//if the action was not explicitly set grab the params from the request
|
||||
if (escapeAmp) {
|
||||
buildParametersString(params, link, AMP, true);
|
||||
parametersStringBuilder.buildParametersString(params, link, AMP);
|
||||
} else {
|
||||
buildParametersString(params, link, "&", true);
|
||||
parametersStringBuilder.buildParametersString(params, link, "&");
|
||||
}
|
||||
|
||||
String result = link.toString();
|
||||
@@ -197,65 +203,35 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds parameters assigned to url - a query string
|
||||
* @param params a set of params to assign
|
||||
* @param link a based url
|
||||
* @param paramSeparator separator used
|
||||
* @deprecated since Struts 6.1.0, use {@link ParametersStringBuilder} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator) {
|
||||
buildParametersString(params, link, paramSeparator, true);
|
||||
parametersStringBuilder.buildParametersString(params, link, paramSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds parameters assigned to url - a query string
|
||||
* @param params a set of params to assign
|
||||
* @param link a based url
|
||||
* @param paramSeparator separator used
|
||||
* @param encode if true, parameters will be encoded - ignored
|
||||
* @deprecated since Struts 6.1.0, use {@link #buildParametersString(Map, StringBuilder, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator, boolean encode) {
|
||||
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 != null ? paramValue.toString() : StringUtils.EMPTY, encode));
|
||||
|
||||
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 != null ? paramValue.toString() : StringUtils.EMPTY, encode));
|
||||
|
||||
if (i < array.length - 1) {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
link.append(buildParameterSubstring(name, value != null ? value.toString() : StringUtils.EMPTY, encode));
|
||||
}
|
||||
|
||||
if (iter.hasNext()) {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
buildParametersString(params, link, paramSeparator);
|
||||
}
|
||||
|
||||
protected boolean isValidScheme(String scheme) {
|
||||
return HTTP_PROTOCOL.equals(scheme) || HTTPS_PROTOCOL.equals(scheme);
|
||||
}
|
||||
|
||||
private String buildParameterSubstring(String name, String value, boolean encode) {
|
||||
String encodedName = encode ? encoder.encode(name) : name;
|
||||
String encodedValue = encode ? encoder.encode(value) : value;
|
||||
return encodedName + '=' + encodedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the URL using {@link UrlEncoder#encode} with the encoding specified in the configuration.
|
||||
*
|
||||
|
||||
@@ -279,6 +279,12 @@ struts.ognl.expressionMaxLength=256
|
||||
### These formatters are using a slightly different patterns, please check JavaDocs of both and more details is in WW-5016
|
||||
struts.date.formatter=dateTimeFormatter
|
||||
|
||||
### Defines which instance of ParametersStringBuilder to use, Struts provides just one instance:
|
||||
### - strutsParametersStringBuilder
|
||||
### The builder is used by UrlHelp to create a proper query string out of provided parameters map
|
||||
struts.url.parametersStringBuilder=strutsParametersStringBuilder
|
||||
|
||||
### Defines which instances of encoder and decoder to use, Struts provides one default implementation for each
|
||||
struts.url.encoder=strutsUrlEncoder
|
||||
struts.url.decoder=strutsUrlDecoder
|
||||
|
||||
|
||||
@@ -313,6 +313,8 @@
|
||||
<bean type="com.opensymphony.xwork2.ognl.BeanInfoCacheFactory" name="struts"
|
||||
class="com.opensymphony.xwork2.ognl.DefaultOgnlBeanInfoCacheFactory" scope="singleton"/>
|
||||
|
||||
<bean type="org.apache.struts2.url.ParametersStringBuilder" name="strutsParametersStringBuilder"
|
||||
class="org.apache.struts2.url.StrutsParametersStringBuilder" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.url.UrlEncoder" name="strutsUrlEncoder"
|
||||
class="org.apache.struts2.url.StrutsUrlEncoder" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.url.UrlDecoder" name="strutsUrlDecoder"
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ public class StrutsBackgroundProcessTest extends StrutsInternalTestCase {
|
||||
executor.execute(bp);
|
||||
}
|
||||
|
||||
Thread.sleep(300);
|
||||
Thread.sleep(400);
|
||||
|
||||
for (BackgroundProcess bp : bps) {
|
||||
assertTrue("Process is still active: " + bp, bp.isDone());
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.url;
|
||||
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class StrutsParametersStringBuilderTest {
|
||||
|
||||
private ParametersStringBuilder builder;
|
||||
|
||||
@Test
|
||||
public void testBuildParametersStringWithUrlHavingSomeExistingParameters() {
|
||||
String expectedUrl = "http://localhost:8080/myContext/myPage.jsp?initParam=initValue&param1=value1&param2=value2&param3%22%3CsCrIpT%3Ealert%281%29%3B%3C%2FsCrIpT%3E=value3";
|
||||
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("param1", "value1");
|
||||
parameters.put("param2", "value2");
|
||||
parameters.put("param3\"<sCrIpT>alert(1);</sCrIpT>", "value3");
|
||||
|
||||
StringBuilder url = new StringBuilder("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
|
||||
|
||||
builder.buildParametersString(parameters, url, UrlHelper.AMP);
|
||||
|
||||
assertEquals(expectedUrl, url.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildParametersStringWithJavaScriptInjected() {
|
||||
String expectedUrl = "http://localhost:8080/myContext/myPage.jsp?initParam=initValue&param1=value1&param2=value2&param3%22%3Cscript+type%3D%22text%2Fjavascript%22%3Ealert%281%29%3B%3C%2Fscript%3E=value3";
|
||||
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("param1", "value1");
|
||||
parameters.put("param2", "value2");
|
||||
parameters.put("param3\"<script type=\"text/javascript\">alert(1);</script>", "value3");
|
||||
|
||||
StringBuilder url = new StringBuilder("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
|
||||
|
||||
builder.buildParametersString(parameters, url, UrlHelper.AMP);
|
||||
|
||||
assertEquals(expectedUrl, url.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildParametersStringWithEmptyListParameters() {
|
||||
String expectedUrl = "https://www.nowhere.com/myworld.html";
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("param1", new String[]{});
|
||||
parameters.put("param2", new ArrayList<>());
|
||||
StringBuilder url = new StringBuilder("https://www.nowhere.com/myworld.html");
|
||||
builder.buildParametersString(parameters, url, UrlHelper.AMP);
|
||||
assertEquals(expectedUrl, url.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildParametersStringWithListParameters() {
|
||||
String expectedUrl = "https://www.nowhere.com/myworld.html?param1=x¶m2=y¶m2=z";
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("param1", new String[]{"x"});
|
||||
parameters.put("param2", new ArrayList<String>() {
|
||||
{
|
||||
add("y");
|
||||
add("z");
|
||||
}
|
||||
});
|
||||
StringBuilder url = new StringBuilder("https://www.nowhere.com/myworld.html");
|
||||
builder.buildParametersString(parameters, url, "&");
|
||||
assertEquals(expectedUrl, url.toString());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
builder = new StrutsParametersStringBuilder(new StrutsUrlEncoder());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.url;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -105,6 +106,13 @@ public class StrutsUrlDecoderTest {
|
||||
assertEquals("xxxxA", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecoding() {
|
||||
String result = decoder.decode("%E6%96%B0%E8%81%9E");
|
||||
|
||||
assertEquals("\u65b0\u805e", result);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.decoder = new StrutsUrlDecoder();
|
||||
|
||||
@@ -82,6 +82,13 @@ public class StrutsUrlEncoderTest {
|
||||
assertEquals("%25xxxx", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncoding() {
|
||||
String result = encoder.encode("\u65b0\u805e");
|
||||
|
||||
assertEquals("%E6%96%B0%E8%81%9E", result);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.encoder = new StrutsUrlEncoder();
|
||||
|
||||
@@ -18,36 +18,30 @@
|
||||
*/
|
||||
package org.apache.struts2.views.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Scope.Strategy;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.url.StrutsParametersStringBuilder;
|
||||
import org.apache.struts2.url.StrutsUrlDecoder;
|
||||
import org.apache.struts2.url.StrutsUrlEncoder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Test case for DefaultUrlHelper.
|
||||
*
|
||||
*/
|
||||
public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
|
||||
private StubContainer stubContainer;
|
||||
private DefaultUrlHelper urlHelper;
|
||||
|
||||
public void testForceAddSchemeHostAndPort() throws Exception {
|
||||
public void testForceAddSchemeHostAndPort() {
|
||||
String expectedUrl = "http://localhost/contextPath/path1/path2/myAction.action";
|
||||
|
||||
Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
|
||||
@@ -64,7 +58,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
|
||||
public void testDoNotForceAddSchemeHostAndPort() throws Exception {
|
||||
public void testDoNotForceAddSchemeHostAndPort() {
|
||||
String expectedUrl = "/contextPath/path1/path2/myAction.action";
|
||||
|
||||
Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
|
||||
@@ -80,7 +74,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
assertEquals(expectedUrl, result);
|
||||
}
|
||||
|
||||
public void testForceAddSchemeHostAndPortWithNonStandardPort() throws Exception {
|
||||
public void testForceAddSchemeHostAndPortWithNonStandardPort() {
|
||||
String expectedUrl = "http://localhost:9090/contextPath/path1/path2/myAction.action";
|
||||
|
||||
Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
|
||||
@@ -97,39 +91,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
|
||||
public void testBuildParametersStringWithUrlHavingSomeExistingParameters() throws Exception {
|
||||
String expectedUrl = "http://localhost:8080/myContext/myPage.jsp?initParam=initValue&param1=value1&param2=value2&param3%22%3CsCrIpT%3Ealert%281%29%3B%3C%2FsCrIpT%3E=value3";
|
||||
|
||||
Map parameters = new LinkedHashMap();
|
||||
parameters.put("param1", "value1");
|
||||
parameters.put("param2", "value2");
|
||||
parameters.put("param3\"<sCrIpT>alert(1);</sCrIpT>","value3");
|
||||
|
||||
StringBuilder url = new StringBuilder("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
|
||||
|
||||
urlHelper.buildParametersString(parameters, url, UrlHelper.AMP);
|
||||
|
||||
assertEquals(
|
||||
expectedUrl, url.toString());
|
||||
}
|
||||
|
||||
public void testBuildParametersStringWithJavaScriptInjected() throws Exception {
|
||||
String expectedUrl = "http://localhost:8080/myContext/myPage.jsp?initParam=initValue&param1=value1&param2=value2&param3%22%3Cscript+type%3D%22text%2Fjavascript%22%3Ealert%281%29%3B%3C%2Fscript%3E=value3";
|
||||
|
||||
Map parameters = new LinkedHashMap();
|
||||
parameters.put("param1", "value1");
|
||||
parameters.put("param2", "value2");
|
||||
parameters.put("param3\"<script type=\"text/javascript\">alert(1);</script>","value3");
|
||||
|
||||
StringBuilder url = new StringBuilder("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
|
||||
|
||||
urlHelper.buildParametersString(parameters, url, UrlHelper.AMP);
|
||||
|
||||
assertEquals(
|
||||
expectedUrl, url.toString());
|
||||
}
|
||||
|
||||
public void testForceAddNullSchemeHostAndPort() throws Exception {
|
||||
public void testForceAddNullSchemeHostAndPort() {
|
||||
String expectedUrl = "http://localhost/contextPath/path1/path2/myAction.action";
|
||||
|
||||
Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
|
||||
@@ -144,14 +106,14 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
expectedUrl);
|
||||
|
||||
String result = urlHelper.buildUrl("/path1/path2/myAction.action",
|
||||
(HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), null,
|
||||
null, true, true, true);
|
||||
(HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), null,
|
||||
null, true, true, true);
|
||||
assertEquals(expectedUrl, result);
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
|
||||
public void testForceAddNullSchemeHostAndPort2() throws Exception {
|
||||
public void testForceAddNullSchemeHostAndPort2() {
|
||||
String expectedUrl = "http://localhost:8080/contextPath/path1/path2/myAction.action";
|
||||
|
||||
Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
|
||||
@@ -166,9 +128,9 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
expectedUrl);
|
||||
|
||||
String result = urlHelper.buildUrl("/path1/path2/myAction.action",
|
||||
(HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), null,
|
||||
null, true, true, true);
|
||||
(HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), null,
|
||||
null, true, true, true);
|
||||
assertEquals(expectedUrl, result);
|
||||
mockHttpServletRequest.verify();
|
||||
}
|
||||
@@ -184,7 +146,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
|
||||
|
||||
String actualUrl = urlHelper.buildUrl(expectedUrl, (HttpServletRequest) mockHttpServletRequest.proxy(),
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), new HashMap());
|
||||
(HttpServletResponse) mockHttpServletResponse.proxy(), new HashMap<>());
|
||||
assertEquals(expectedUrl, actualUrl);
|
||||
}
|
||||
|
||||
@@ -199,7 +161,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "my.actionName";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", "world");
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -218,7 +180,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "my.actionName";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", "world");
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -234,7 +196,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "my.actionName";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -259,7 +221,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "/MyAction.action";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -284,7 +246,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "/MyAction.action";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -313,7 +275,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "/MyAction.action";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -342,7 +304,7 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "/MyAction.action";
|
||||
TreeMap params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
params.put("hello", new String[]{"earth", "mars"});
|
||||
params.put("foo", "bar");
|
||||
|
||||
@@ -371,15 +333,15 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
|
||||
|
||||
String actionName = "promo.html";
|
||||
Map params = new TreeMap();
|
||||
TreeMap<String, Object> params = new TreeMap<>();
|
||||
|
||||
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", false);
|
||||
public void testParseQuery() {
|
||||
Map<String, Object> result = urlHelper.parseQueryString("aaa=aaaval&bbb=bbbval&ccc=&%3Ca%22%3E=%3Cval%3E", false);
|
||||
|
||||
assertEquals(result.get("aaa"), "aaaval");
|
||||
assertEquals(result.get("bbb"), "bbbval");
|
||||
@@ -387,38 +349,21 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
assertEquals(result.get("<a\">"), "<val>");
|
||||
}
|
||||
|
||||
public void testParseEmptyQuery() throws Exception {
|
||||
Map result = urlHelper.parseQueryString("", false);
|
||||
public void testParseEmptyQuery() {
|
||||
Map<String, Object> result = urlHelper.parseQueryString("", false);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), 0);
|
||||
}
|
||||
|
||||
public void testParseNullQuery() throws Exception {
|
||||
Map result = urlHelper.parseQueryString(null, false);
|
||||
public void testParseNullQuery() {
|
||||
Map<String, Object> result = urlHelper.parseQueryString(null, false);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), 0);
|
||||
}
|
||||
|
||||
|
||||
public void testEncode() throws Exception {
|
||||
setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
|
||||
String result = urlHelper.encode("\u65b0\u805e");
|
||||
String expectedResult = "%E6%96%B0%E8%81%9E";
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
}
|
||||
|
||||
public void testDecode() throws Exception {
|
||||
setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
|
||||
String result = urlHelper.decode("%E6%96%B0%E8%81%9E");
|
||||
String expectedResult = "\u65b0\u805e";
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
}
|
||||
|
||||
public void testDecodeSpacesInQueryString() throws Exception {
|
||||
public void testDecodeSpacesInQueryString() {
|
||||
Map<String, Object> queryParameters = urlHelper.parseQueryString("name=value+with+space", false);
|
||||
|
||||
assertTrue(queryParameters.containsKey("name"));
|
||||
@@ -428,18 +373,16 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
stubContainer = new StubContainer(container);
|
||||
StubContainer stubContainer = new StubContainer(container);
|
||||
ActionContext.getContext().withContainer(stubContainer);
|
||||
urlHelper = new DefaultUrlHelper();
|
||||
urlHelper.setEncoder(new StrutsUrlEncoder());
|
||||
StrutsUrlEncoder encoder = new StrutsUrlEncoder();
|
||||
urlHelper.setParametersStringBuilder(new StrutsParametersStringBuilder(encoder));
|
||||
urlHelper.setEncoder(encoder);
|
||||
urlHelper.setDecoder(new StrutsUrlDecoder());
|
||||
}
|
||||
|
||||
private void setProp(String key, String val) {
|
||||
stubContainer.overrides.put(key, val);
|
||||
}
|
||||
|
||||
class StubContainer implements Container {
|
||||
static class StubContainer implements Container {
|
||||
|
||||
Container parent;
|
||||
|
||||
@@ -448,7 +391,9 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public Map<String, Object> overrides = new HashMap<String,Object>();
|
||||
public Map<String, Object> overrides = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getInstance(Class<T> type, String name) {
|
||||
if (String.class.isAssignableFrom(type) && overrides.containsKey(name)) {
|
||||
return (T) overrides.get(name);
|
||||
|
||||
+19
-6
@@ -26,6 +26,9 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
|
||||
import org.apache.struts2.junit.StrutsTestCase;
|
||||
import org.apache.struts2.url.StrutsParametersStringBuilder;
|
||||
import org.apache.struts2.url.StrutsUrlDecoder;
|
||||
import org.apache.struts2.url.StrutsUrlEncoder;
|
||||
import org.apache.struts2.views.util.DefaultUrlHelper;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
@@ -33,6 +36,9 @@ import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
public class JSONActionRedirectResultTest extends StrutsTestCase {
|
||||
|
||||
private DefaultActionMapper actionMapper;
|
||||
private DefaultUrlHelper urlHelper;
|
||||
|
||||
MockActionInvocation invocation;
|
||||
MockHttpServletResponse response;
|
||||
MockServletContext servletContext;
|
||||
@@ -43,8 +49,8 @@ public class JSONActionRedirectResultTest extends StrutsTestCase {
|
||||
public void testNormalRedirect() throws Exception {
|
||||
JSONActionRedirectResult result = new JSONActionRedirectResult();
|
||||
result.setActionName("targetAction");
|
||||
result.setActionMapper(new DefaultActionMapper());
|
||||
result.setUrlHelper(new DefaultUrlHelper());
|
||||
result.setActionMapper(actionMapper);
|
||||
result.setUrlHelper(urlHelper);
|
||||
|
||||
Object action = new Object();
|
||||
stack.push(action);
|
||||
@@ -62,8 +68,8 @@ public class JSONActionRedirectResultTest extends StrutsTestCase {
|
||||
public void testJsonRedirect() throws Exception {
|
||||
JSONActionRedirectResult result = new JSONActionRedirectResult();
|
||||
result.setActionName("targetAction");
|
||||
result.setActionMapper(new DefaultActionMapper());
|
||||
result.setUrlHelper(new DefaultUrlHelper());
|
||||
result.setActionMapper(actionMapper);
|
||||
result.setUrlHelper(urlHelper);
|
||||
|
||||
request.setParameter("struts.enableJSONValidation", "true");
|
||||
request.setParameter("struts.validateOnly", "false");
|
||||
@@ -82,8 +88,8 @@ public class JSONActionRedirectResultTest extends StrutsTestCase {
|
||||
public void testValidateOnlyFalse() throws Exception {
|
||||
JSONActionRedirectResult result = new JSONActionRedirectResult();
|
||||
result.setActionName("targetAction");
|
||||
result.setActionMapper(new DefaultActionMapper());
|
||||
result.setUrlHelper(new DefaultUrlHelper());
|
||||
result.setActionMapper(actionMapper);
|
||||
result.setUrlHelper(urlHelper);
|
||||
|
||||
request.setParameter("struts.enableJSONValidation", "true");
|
||||
request.setParameter("struts.validateOnly", "true");
|
||||
@@ -118,5 +124,12 @@ public class JSONActionRedirectResultTest extends StrutsTestCase {
|
||||
MockActionProxy mockActionProxy = new MockActionProxy();
|
||||
mockActionProxy.setConfig(new ActionConfig.Builder(null, null, null).build());
|
||||
this.invocation.setProxy(mockActionProxy);
|
||||
|
||||
this.actionMapper = new DefaultActionMapper();
|
||||
this.urlHelper = new DefaultUrlHelper();
|
||||
StrutsUrlEncoder encoder = new StrutsUrlEncoder();
|
||||
this.urlHelper.setParametersStringBuilder(new StrutsParametersStringBuilder(encoder));
|
||||
this.urlHelper.setEncoder(encoder);
|
||||
this.urlHelper.setDecoder(new StrutsUrlDecoder());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user