From 0ae1fd2c3a57a4448adf82f938ee32454b49fed9 Mon Sep 17 00:00:00 2001 From: whl Date: Sun, 20 Apr 2025 13:53:47 +0800 Subject: [PATCH 1/2] Fix uri format with duplicate fields Signed-off-by: whl --- .../org/springframework/web/util/HierarchicalUriComponents.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java index 45521b4d7d94..f2d863197a62 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java @@ -443,7 +443,7 @@ private MultiValueMap expandQueryParams(UriTemplateVariables var UriTemplateVariables queryVariables = new QueryUriTemplateVariables(variables); this.queryParams.forEach((key, values) -> { String name = expandUriComponent(key, queryVariables, this.variableEncoder); - List expandedValues = new ArrayList<>(values.size()); + List expandedValues = result.getOrDefault(name, new ArrayList<>(values.size())); for (String value : values) { expandedValues.add(expandUriComponent(value, queryVariables, this.variableEncoder)); } From 5390b4e494fa38822b4eb1f372a7e4e86c167a52 Mon Sep 17 00:00:00 2001 From: whl Date: Sun, 20 Apr 2025 22:21:29 +0800 Subject: [PATCH 2/2] parse uri with duplicate query keys Signed-off-by: whl --- .../web/util/UriComponentsBuilderTests.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index f31c71bb1a80..6376a680dbcc 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -629,6 +629,20 @@ void parseBuildAndExpandHierarchical(ParserType parserType) { assertThat(uri.toString()).isEqualTo("ws://example.org:7777/path?q=1#foo"); } + @ParameterizedTest + @EnumSource + void parseBuildAndExpandHierarchicalWithDuplicateQueryKeys(ParserType parserType) { + UriComponents result = UriComponentsBuilder.fromUriString("/?{pk1}={pv1}&{pk2}={pv2}", parserType) + .buildAndExpand("k1", "v1", "k1", "v2"); + assertThat(result.getQuery()).isEqualTo("k1=v1&k1=v2"); + assertThat(result.getQueryParams().get("k1")).containsExactly("v1", "v2"); + + UriComponents result2 = UriComponentsBuilder.fromUriString("/?{pk1}={pv1}&{pk2}={pv2}", parserType) + .buildAndExpand(Map.of("pk1", "k1", "pv1", "v1", "pk2", "k1", "pv2", "v2")); + assertThat(result2.getQuery()).isEqualTo("k1=v1&k1=v2"); + assertThat(result.getQueryParams().get("k1")).containsExactly("v1", "v2"); + } + @ParameterizedTest @EnumSource void buildAndExpandOpaque(ParserType parserType) {