Skip to content

Commit a57d428

Browse files
committed
Support {/var} syntax in UriComponentsBuilder
Issue: SPR-12750
1 parent 6a96c26 commit a57d428

File tree

3 files changed

+52
-12
lines changed

3 files changed

+52
-12
lines changed

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

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -716,18 +716,35 @@ public void addPathSegments(String... pathSegments) {
716716
}
717717

718718
public void addPath(String path) {
719-
if (StringUtils.hasText(path)) {
720-
PathSegmentComponentBuilder psBuilder = getLastBuilder(PathSegmentComponentBuilder.class);
721-
FullPathComponentBuilder fpBuilder = getLastBuilder(FullPathComponentBuilder.class);
722-
if (psBuilder != null) {
723-
path = path.startsWith("/") ? path : "/" + path;
724-
}
725-
if (fpBuilder == null) {
726-
fpBuilder = new FullPathComponentBuilder();
727-
this.builders.add(fpBuilder);
728-
}
729-
fpBuilder.append(path);
719+
if (!StringUtils.hasText(path)) {
720+
return;
721+
}
722+
int startIndex = path.indexOf("{/");
723+
while (startIndex != -1) {
724+
String pathToAdd = path.substring(0, startIndex);
725+
addPathInternal(pathToAdd);
726+
727+
int endIndex = path.indexOf("}", startIndex);
728+
String pathSegmentToAdd = "{" + path.substring(startIndex + 2, endIndex) + "}";
729+
addPathSegments(pathSegmentToAdd);
730+
731+
path = (endIndex >= path.length()) ? "" : path.substring(endIndex + 1);
732+
startIndex = path.indexOf("{/");
733+
}
734+
addPathInternal(path);
735+
}
736+
737+
private void addPathInternal(String path) {
738+
PathSegmentComponentBuilder psBuilder = getLastBuilder(PathSegmentComponentBuilder.class);
739+
FullPathComponentBuilder fpBuilder = getLastBuilder(FullPathComponentBuilder.class);
740+
if (psBuilder != null) {
741+
path = path.startsWith("/") ? path : "/" + path;
742+
}
743+
if (fpBuilder == null) {
744+
fpBuilder = new FullPathComponentBuilder();
745+
this.builders.add(fpBuilder);
730746
}
747+
fpBuilder.append(path);
731748
}
732749

733750
@SuppressWarnings("unchecked")

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ public void fromUriStringQueryParamWithReservedCharInValue() throws URISyntaxExc
195195
assertEquals("1USD=?EUR", result.getQueryParams().getFirst("q"));
196196
}
197197

198+
//SPR-12750
199+
200+
@Test
201+
public void fromUriStringWithVariablesRfc6570() {
202+
String url = "http://example.com/part1/{/part2}/{var1}/url/{/urlvar}/";
203+
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url);
204+
UriComponents uriComponents = builder.build().expand("part/2", "var/1", "url/var").encode();
205+
assertEquals("/part1/part%2F2/var/1/url/url%2Fvar/", uriComponents.getPath());
206+
}
207+
198208
// SPR-10779
199209

200210
@Test

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2015 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.
@@ -98,6 +98,19 @@ public void expandMapUnboundVariables() throws Exception {
9898
template.expand(uriVariables);
9999
}
100100

101+
//SPR-12750
102+
103+
@Test
104+
public void expandMapForRFC6570() throws Exception {
105+
Map<String, String> uriVariables = new HashMap<String, String>(2);
106+
uriVariables.put("hotel", "1");
107+
uriVariables.put("publicpath", "pics/logo.png");
108+
uriVariables.put("scale", "150x150");
109+
UriTemplate template = new UriTemplate("/hotels/{hotel}/pic/{/publicpath}/size/{scale}");
110+
URI result = template.expand(uriVariables);
111+
assertEquals("Invalid expanded template", new URI("/hotels/1/pic/pics%2Flogo.png/size/150x150"), result);
112+
}
113+
101114
@Test
102115
public void expandEncoded() throws Exception {
103116
UriTemplate template = new UriTemplate("http://example.com/hotel list/{hotel}");

0 commit comments

Comments
 (0)