Skip to content

Commit 93e42b8

Browse files
committed
Copy queryParams MultiValueMap through deepCopy (for independent List entries)
Closes gh-25423
1 parent 7077346 commit 93e42b8

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -108,7 +108,7 @@ public class UriComponentsBuilder implements Cloneable {
108108

109109
private CompositePathComponentBuilder pathBuilder;
110110

111-
private final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
111+
private LinkedMultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
112112

113113
private String fragment;
114114

@@ -135,7 +135,7 @@ protected UriComponentsBuilder(UriComponentsBuilder other) {
135135
this.host = other.host;
136136
this.port = other.port;
137137
this.pathBuilder = other.pathBuilder.cloneBuilder();
138-
this.queryParams.putAll(other.queryParams);
138+
this.queryParams = other.queryParams.deepCopy();
139139
this.fragment = other.fragment;
140140
}
141141

spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@
3636
import static org.junit.Assert.*;
3737

3838
/**
39-
* Unit tests for {@link org.springframework.web.util.UriComponentsBuilder}.
39+
* Unit tests for {@link UriComponentsBuilder}.
4040
*
4141
* @author Arjen Poutsma
4242
* @author Phillip Webb
@@ -557,7 +557,7 @@ public void pathSegmentsSomeEmpty() {
557557
}
558558

559559
@Test // SPR-12398
560-
public void pathWithDuplicateSlashes() throws URISyntaxException {
560+
public void pathWithDuplicateSlashes() {
561561
UriComponents uriComponents = UriComponentsBuilder.fromPath("/foo/////////bar").build();
562562
assertEquals("/foo/bar", uriComponents.getPath());
563563
}
@@ -727,26 +727,28 @@ public void parsesEmptyUri() {
727727
assertThat(components.toString(), equalTo(""));
728728
}
729729

730-
@Test
731-
public void testClone() throws URISyntaxException {
730+
@Test // gh-25243
731+
public void testCloneAndMerge() {
732732
UriComponentsBuilder builder1 = UriComponentsBuilder.newInstance();
733-
builder1.scheme("http").host("e1.com").path("/p1").pathSegment("ps1").queryParam("q1").fragment("f1");
733+
builder1.scheme("http").host("e1.com").path("/p1").pathSegment("ps1").queryParam("q1", "x").fragment("f1");
734734

735-
UriComponentsBuilder builder2 = (UriComponentsBuilder) builder1.clone();
735+
UriComponentsBuilder builder2 = builder1.cloneBuilder();
736736
builder2.scheme("https").host("e2.com").path("p2").pathSegment("ps2").queryParam("q2").fragment("f2");
737737

738+
builder1.queryParam("q1", "y"); // one more entry for an existing parameter
739+
738740
UriComponents result1 = builder1.build();
739741
assertEquals("http", result1.getScheme());
740742
assertEquals("e1.com", result1.getHost());
741743
assertEquals("/p1/ps1", result1.getPath());
742-
assertEquals("q1", result1.getQuery());
744+
assertEquals("q1=x&q1=y", result1.getQuery());
743745
assertEquals("f1", result1.getFragment());
744746

745-
UriComponents result2 = builder2.build();
747+
UriComponents result2 = builder2.buildAndExpand("ps2;a");
746748
assertEquals("https", result2.getScheme());
747749
assertEquals("e2.com", result2.getHost());
748750
assertEquals("/p1/ps1/p2/ps2", result2.getPath());
749-
assertEquals("q1&q2", result2.getQuery());
751+
assertEquals("q1=x&q2", result2.getQuery());
750752
assertEquals("f2", result2.getFragment());
751753
}
752754

0 commit comments

Comments
 (0)