You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2023/06/20 19:24:03 UTC
[struts] branch WW-5310-fragment updated: WW-5310 Deprecates the old API in favour of new one
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch WW-5310-fragment
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/WW-5310-fragment by this push:
new e5c7a30f3 WW-5310 Deprecates the old API in favour of new one
e5c7a30f3 is described below
commit e5c7a30f3d4c608f1728d949f1a0ef0a4167f4ba
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Tue Jun 20 21:23:57 2023 +0200
WW-5310 Deprecates the old API in favour of new one
---
.../struts2/components/ServletUrlRenderer.java | 17 +++--
.../struts2/result/ServletDispatcherResult.java | 8 +-
.../org/apache/struts2/url/QueryStringParser.java | 14 +++-
.../org/apache/struts2/url/QueryStringResult.java | 89 ++++++++++++++++++++++
.../struts2/url/StrutsQueryStringParser.java | 44 +++++------
.../struts2/url/StrutsQueryStringParserTest.java | 23 +++---
6 files changed, 146 insertions(+), 49 deletions(-)
diff --git a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
index d5281a8a0..18d866542 100644
--- a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
+++ b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
@@ -30,6 +30,7 @@ import org.apache.struts2.StrutsException;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.url.QueryStringParser;
+import org.apache.struts2.url.QueryStringResult;
import org.apache.struts2.views.util.UrlHelper;
import java.io.IOException;
@@ -159,10 +160,10 @@ public class ServletUrlRenderer implements UrlRenderer {
}
}
- Map<String, Object> actionParams = null;
+ QueryStringResult queryStringResult = QueryStringResult.empty();
if (action != null && action.indexOf('?') > 0) {
String queryString = action.substring(action.indexOf('?') + 1);
- actionParams = queryStringParser.parse(queryString, false);
+ queryStringResult = queryStringParser.parse(queryString);
action = action.substring(0, action.indexOf('?'));
}
@@ -176,7 +177,7 @@ public class ServletUrlRenderer implements UrlRenderer {
ActionMapping mapping = new ActionMapping(actionName, namespace, actionMethod, formComponent.parameters);
String result = urlHelper.buildUrl(formComponent.actionMapper.getUriFromActionMapping(mapping),
- formComponent.request, formComponent.response, actionParams, scheme, formComponent.includeContext, true, false, false);
+ formComponent.request, formComponent.response, queryStringResult.getQueryParams(), scheme, formComponent.includeContext, true, false, false);
formComponent.addParameter("action", result);
// let's try to get the actual action class and name
@@ -213,7 +214,7 @@ public class ServletUrlRenderer implements UrlRenderer {
LOG.warn("No configuration found for the specified action: '{}' in namespace: '{}'. Form action defaulting to 'action' attribute's literal value.", actionName, namespace);
}
- String result = urlHelper.buildUrl(action, formComponent.request, formComponent.response, actionParams, scheme, formComponent.includeContext, true);
+ String result = urlHelper.buildUrl(action, formComponent.request, formComponent.response, queryStringResult.getQueryParams(), scheme, formComponent.includeContext, true);
formComponent.addParameter("action", result);
// namespace: cut out anything between the start and the last /
@@ -291,7 +292,11 @@ public class ServletUrlRenderer implements UrlRenderer {
private void includeGetParameters(UrlProvider urlComponent) {
String query = extractQueryString(urlComponent);
- mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), queryStringParser.parse(query, false));
+ QueryStringResult result = queryStringParser.parse(query);
+ mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), result.getQueryParams());
+ if (!result.getQueryFragment().isEmpty()) {
+ urlComponent.setAnchor(result.getQueryFragment());
+ }
}
private String extractQueryString(UrlProvider urlComponent) {
@@ -339,7 +344,7 @@ public class ServletUrlRenderer implements UrlRenderer {
if (StringUtils.contains(value, "?")) {
String queryString = value.substring(value.indexOf('?') + 1);
- mergedParams = queryStringParser.parse(queryString, false);
+ mergedParams = new LinkedHashMap<>(queryStringParser.parse(queryString).getQueryParams());
for (Map.Entry<String, ?> entry : contextParameters.entrySet()) {
if (!mergedParams.containsKey(entry.getKey())) {
mergedParams.put(entry.getKey(), entry.getValue());
diff --git a/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java b/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java
index 6bc86725d..e1bc17eb8 100644
--- a/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java
+++ b/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java
@@ -28,12 +28,12 @@ import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.url.QueryStringParser;
+import org.apache.struts2.url.QueryStringResult;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
-import java.util.Map;
/**
* <!-- START SNIPPET: description -->
@@ -140,9 +140,9 @@ public class ServletDispatcherResult extends StrutsResultSupport {
if (StringUtils.isNotEmpty(finalLocation) && finalLocation.indexOf('?') > 0) {
String queryString = finalLocation.substring(finalLocation.indexOf('?') + 1);
HttpParameters parameters = getParameters(invocation);
- Map<String, Object> queryParams = queryStringParser.parse(queryString, true);
- if (queryParams != null && !queryParams.isEmpty()) {
- parameters = HttpParameters.create(queryParams).withParent(parameters).build();
+ QueryStringResult queryParams = queryStringParser.parse(queryString);
+ if (!queryParams.isEmpty()) {
+ parameters = HttpParameters.create(queryParams.getQueryParams()).withParent(parameters).build();
invocation.getInvocationContext().withParameters(parameters);
// put to extraContext, see Dispatcher#createContextMap
invocation.getInvocationContext().getContextMap().put("parameters", parameters);
diff --git a/core/src/main/java/org/apache/struts2/url/QueryStringParser.java b/core/src/main/java/org/apache/struts2/url/QueryStringParser.java
index 0f48cd293..d607ab817 100644
--- a/core/src/main/java/org/apache/struts2/url/QueryStringParser.java
+++ b/core/src/main/java/org/apache/struts2/url/QueryStringParser.java
@@ -22,11 +22,23 @@ import java.io.Serializable;
import java.util.Map;
/**
- * Used to parse Http Query String into a Map of parameters
+ * Used to parse Http Query String into a map of parameters with support for fragment
* @since Struts 6.1.0
*/
public interface QueryStringParser extends Serializable {
+ /**
+ * @deprecated since Struts 6.2.0, use {@link #parse(String)} instead
+ */
+ @Deprecated
Map<String, Object> parse(String queryString, boolean forceValueArray);
+ /**
+ *
+ * @param queryString a query string to parse
+ * @return a {@link QueryStringResult} of parsing the query string
+ * @since Struts 6.2.0
+ */
+ QueryStringResult parse(String queryString);
+
}
diff --git a/core/src/main/java/org/apache/struts2/url/QueryStringResult.java b/core/src/main/java/org/apache/struts2/url/QueryStringResult.java
new file mode 100644
index 000000000..0836d2eb8
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/url/QueryStringResult.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class QueryStringResult {
+
+ private final Map<String, Object> queryParams;
+ private String queryFragment;
+
+ public static QueryStringResult empty() {
+ return new QueryStringResult(Collections.emptyMap(), "");
+ }
+
+ public static QueryStringResult create() {
+ return new QueryStringResult(new LinkedHashMap<>(), "");
+ }
+
+ private QueryStringResult(Map<String, Object> queryParams, String queryFragment) {
+ this.queryParams = queryParams;
+ this.queryFragment = queryFragment;
+ }
+
+ public QueryStringResult addParam(String name, String value) {
+ if (queryParams.containsKey(name)) {
+ // WW-1619 append new param value to existing value(s)
+ Object currentParam = queryParams.get(name);
+ if (currentParam instanceof String) {
+ queryParams.put(name, new String[]{(String) currentParam, value});
+ } else {
+ String[] currentParamValues = (String[]) currentParam;
+ if (currentParamValues != null) {
+ List<String> paramList = new ArrayList<>(Arrays.asList(currentParamValues));
+ paramList.add(value);
+ queryParams.put(name, paramList.toArray(new String[0]));
+ } else {
+ queryParams.put(name, new String[]{value});
+ }
+ }
+ } else {
+ queryParams.put(name, value);
+ }
+
+ return this;
+ }
+
+ public QueryStringResult withQueryFragment(String queryFragment) {
+ this.queryFragment = queryFragment;
+ return this;
+ }
+
+ public Map<String, Object> getQueryParams() {
+ return Collections.unmodifiableMap(queryParams);
+ }
+
+ public String getQueryFragment() {
+ return queryFragment;
+ }
+
+ public boolean contains(String name) {
+ return queryParams.containsKey(name);
+ }
+
+ public boolean isEmpty() {
+ return queryParams.isEmpty();
+ }
+}
diff --git a/core/src/main/java/org/apache/struts2/url/StrutsQueryStringParser.java b/core/src/main/java/org/apache/struts2/url/StrutsQueryStringParser.java
index 4c31d4885..5cc50a01f 100644
--- a/core/src/main/java/org/apache/struts2/url/StrutsQueryStringParser.java
+++ b/core/src/main/java/org/apache/struts2/url/StrutsQueryStringParser.java
@@ -23,11 +23,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
public class StrutsQueryStringParser implements QueryStringParser {
@@ -43,12 +38,17 @@ public class StrutsQueryStringParser implements QueryStringParser {
@Override
public Map<String, Object> parse(String queryString, boolean forceValueArray) {
+ return parse(queryString).getQueryParams();
+ }
+
+ @Override
+ public QueryStringResult parse(String queryString) {
if (StringUtils.isEmpty(queryString)) {
LOG.debug("Query String is empty, returning an empty map");
- return Collections.emptyMap();
+ return QueryStringResult.empty();
}
- Map<String, Object> queryParams = new LinkedHashMap<>();
+ QueryStringResult queryParams = QueryStringResult.create();
String[] params = extractParams(queryString);
for (String param : params) {
if (StringUtils.isBlank(param)) {
@@ -64,9 +64,9 @@ public class StrutsQueryStringParser implements QueryStringParser {
} else {
paramName = param;
}
- extractParam(paramName, paramValue, queryParams, forceValueArray);
+ queryParams = extractParam(paramName, paramValue, queryParams);
}
- return queryParams;
+ return queryParams.withQueryFragment(extractFragment(queryString));
}
private String[] extractParams(String queryString) {
@@ -81,27 +81,17 @@ public class StrutsQueryStringParser implements QueryStringParser {
return params;
}
- private void extractParam(String paramName, String paramValue, Map<String, Object> queryParams, boolean forceValueArray) {
+ private QueryStringResult extractParam(String paramName, String paramValue, QueryStringResult queryParams) {
String decodedParamName = decoder.decode(paramName, true);
String decodedParamValue = decoder.decode(paramValue, true);
+ return queryParams.addParam(decodedParamName, decodedParamValue);
+ }
- if (queryParams.containsKey(decodedParamName) || forceValueArray) {
- // WW-1619 append new param value to existing value(s)
- Object currentParam = queryParams.get(decodedParamName);
- if (currentParam instanceof String) {
- queryParams.put(decodedParamName, new String[]{(String) currentParam, decodedParamValue});
- } else {
- String[] currentParamValues = (String[]) currentParam;
- if (currentParamValues != null) {
- List<String> paramList = new ArrayList<>(Arrays.asList(currentParamValues));
- paramList.add(decodedParamValue);
- queryParams.put(decodedParamName, paramList.toArray(new String[0]));
- } else {
- queryParams.put(decodedParamName, new String[]{decodedParamValue});
- }
- }
- } else {
- queryParams.put(decodedParamName, decodedParamValue);
+ private String extractFragment(String queryString) {
+ int fragmentIndex = queryString.lastIndexOf("#");
+ if (fragmentIndex > -1) {
+ return queryString.substring(fragmentIndex + 1);
}
+ return "";
}
}
diff --git a/core/src/test/java/org/apache/struts2/url/StrutsQueryStringParserTest.java b/core/src/test/java/org/apache/struts2/url/StrutsQueryStringParserTest.java
index 93fd9bbaa..7f44fe834 100644
--- a/core/src/test/java/org/apache/struts2/url/StrutsQueryStringParserTest.java
+++ b/core/src/test/java/org/apache/struts2/url/StrutsQueryStringParserTest.java
@@ -35,7 +35,7 @@ public class StrutsQueryStringParserTest {
@Test
public void testParseQuery() {
- Map<String, Object> result = parser.parse("aaa=aaaval&bbb=bbbval&ccc=&%3Ca%22%3E=%3Cval%3E", false);
+ Map<String, Object> result = parser.parse("aaa=aaaval&bbb=bbbval&ccc=&%3Ca%22%3E=%3Cval%3E").getQueryParams();
assertEquals("aaaval", result.get("aaa"));
assertEquals("bbbval", result.get("bbb"));
@@ -45,7 +45,7 @@ public class StrutsQueryStringParserTest {
@Test
public void testParseQueryIntoArray() {
- Map<String, Object> result = parser.parse("a=1&a=2&a=3", true);
+ Map<String, Object> result = parser.parse("a=1&a=2&a=3").getQueryParams();
Object actual = result.get("a");
assertThat(actual).isInstanceOf(String[].class);
@@ -54,7 +54,7 @@ public class StrutsQueryStringParserTest {
@Test
public void testParseEmptyQuery() {
- Map<String, Object> result = parser.parse("", false);
+ Map<String, Object> result = parser.parse("").getQueryParams();
assertNotNull(result);
assertEquals(0, result.size());
@@ -62,7 +62,7 @@ public class StrutsQueryStringParserTest {
@Test
public void testParseNullQuery() {
- Map<String, Object> result = parser.parse(null, false);
+ Map<String, Object> result = parser.parse(null).getQueryParams();
assertNotNull(result);
assertEquals(0, result.size());
@@ -70,7 +70,7 @@ public class StrutsQueryStringParserTest {
@Test
public void testDecodeSpacesInQueryString() {
- Map<String, Object> queryParameters = parser.parse("name=value+with+space", false);
+ Map<String, Object> queryParameters = parser.parse("name=value+with+space").getQueryParams();
assertTrue(queryParameters.containsKey("name"));
assertEquals("value with space", queryParameters.get("name"));
@@ -78,7 +78,7 @@ public class StrutsQueryStringParserTest {
@Test
public void shouldProperlySplitParamsWithDoubleEqualSign() {
- Map<String, Object> queryParameters = parser.parse("id1=n123=&id2=n3456", false);
+ Map<String, Object> queryParameters = parser.parse("id1=n123=&id2=n3456").getQueryParams();
assertTrue(queryParameters.containsKey("id1"));
assertTrue(queryParameters.containsKey("id2"));
@@ -88,7 +88,7 @@ public class StrutsQueryStringParserTest {
@Test
public void shouldHandleParamWithNoValue1() {
- Map<String, Object> queryParameters = parser.parse("paramNoValue", false);
+ Map<String, Object> queryParameters = parser.parse("paramNoValue").getQueryParams();
assertTrue(queryParameters.containsKey("paramNoValue"));
assertEquals("", queryParameters.get("paramNoValue"));
@@ -96,7 +96,7 @@ public class StrutsQueryStringParserTest {
@Test
public void shouldHandleParamWithNoValue2() {
- Map<String, Object> queryParameters = parser.parse("paramNoValue¶m1=1234", false);
+ Map<String, Object> queryParameters = parser.parse("paramNoValue¶m1=1234").getQueryParams();
assertTrue(queryParameters.containsKey("paramNoValue"));
assertTrue(queryParameters.containsKey("param1"));
@@ -105,10 +105,11 @@ public class StrutsQueryStringParserTest {
@Test
public void shouldHandleParamAndFragment() {
- Map<String, Object> queryParameters = parser.parse("param1=1234#test", false);
+ QueryStringResult queryParameters = parser.parse("param1=1234#test");
- assertTrue(queryParameters.containsKey("param1"));
- assertEquals("1234", queryParameters.get("param1"));
+ assertTrue(queryParameters.getQueryParams().containsKey("param1"));
+ assertEquals("1234", queryParameters.getQueryParams().get("param1"));
+ assertEquals("test", queryParameters.getQueryFragment());
}
@Before