diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index 0a862167d91..8c953234aea 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -155,6 +155,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { this.host = other.host; this.port = other.port; this.pathBuilder = other.pathBuilder.cloneBuilder(); + this.uriVariables.putAll(other.uriVariables); this.queryParams.putAll(other.queryParams); this.fragment = other.fragment; this.encodeTemplate = other.encodeTemplate; 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 4d6166ebba2..24d28be2a95 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 @@ -834,7 +834,7 @@ public class UriComponentsBuilderTests { } @Test - public void testClone() { + public void testCloneAndMerge() { UriComponentsBuilder builder1 = UriComponentsBuilder.newInstance(); builder1.scheme("http").host("e1.com").path("/p1").pathSegment("ps1").queryParam("q1").fragment("f1").encode(); @@ -856,6 +856,37 @@ public class UriComponentsBuilderTests { assertThat(result2.getFragment()).isEqualTo("f2"); } + @Test // gh-24772 + public void testDeepClone() { + HashMap vars = new HashMap<>(); + vars.put("ps1", "foo"); + vars.put("ps2", "bar"); + + UriComponentsBuilder builder1 = UriComponentsBuilder.newInstance(); + builder1.scheme("http").host("e1.com").userInfo("user:pwd").path("/p1").pathSegment("{ps1}") + .pathSegment("{ps2}").queryParam("q1").fragment("f1").uriVariables(vars).encode(); + + UriComponentsBuilder builder2 = (UriComponentsBuilder) builder1.clone(); + + UriComponents result1 = builder1.build(); + assertThat(result1.getScheme()).isEqualTo("http"); + assertThat(result1.getUserInfo()).isEqualTo("user:pwd"); + assertThat(result1.getHost()).isEqualTo("e1.com"); + assertThat(result1.getPath()).isEqualTo("/p1/%s/%s", vars.get("ps1"), vars.get("ps2")); + assertThat(result1.getQuery()).isEqualTo("q1"); + assertThat(result1.getFragment()).isEqualTo("f1"); + assertThat(result1.getSchemeSpecificPart()).isEqualTo(null); + + UriComponents result2 = builder2.build(); + assertThat(result2.getScheme()).isEqualTo("http"); + assertThat(result2.getUserInfo()).isEqualTo("user:pwd"); + assertThat(result2.getHost()).isEqualTo("e1.com"); + assertThat(result2.getPath()).isEqualTo("/p1/%s/%s", vars.get("ps1"), vars.get("ps2")); + assertThat(result2.getQuery()).isEqualTo("q1"); + assertThat(result2.getFragment()).isEqualTo("f1"); + assertThat(result1.getSchemeSpecificPart()).isEqualTo(null); + } + @Test // SPR-11856 public void fromHttpRequestForwardedHeader() { MockHttpServletRequest request = new MockHttpServletRequest();