Skip to content

Commit eb47a4b

Browse files
committed
SPR-5516: RestTemplate should encode the url variables
1 parent 4c0edc2 commit eb47a4b

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

org.springframework.web/src/main/java/org/springframework/web/util/UriTemplate.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
* (<code>{</code>, <code>}</code>), which can be expanded to produce a URI.
3434
* <p/>
3535
* See {@link #expand(Map)}, {@link #expand(String[])}, and {@link #match(String)} for example usages.
36-
*
3736
* @author Arjen Poutsma
3837
* @see <a href="http://bitworking.org/projects/URI-Templates/">URI Templates</a>
38+
* @since 3.0
3939
*/
4040
public final class UriTemplate {
4141

@@ -57,7 +57,6 @@ public final class UriTemplate {
5757

5858
/**
5959
* Constructs a new {@link UriTemplate} with the given string.
60-
*
6160
* @param uriTemplate the uri template string
6261
*/
6362
public UriTemplate(String uriTemplate) {
@@ -69,7 +68,6 @@ public UriTemplate(String uriTemplate) {
6968

7069
/**
7170
* Returns the names of the variables in the template, in order.
72-
*
7371
* @return the template variable names
7472
*/
7573
public List<String> getVariableNames() {
@@ -89,7 +87,6 @@ public List<String> getVariableNames() {
8987
* System.out.println(template.expand(uriVariables));
9088
* </pre>
9189
* will print: <blockquote><code>http://example.com/hotels/1/bookings/42</code></blockquote>
92-
*
9390
* @param uriVariables the map of uri variables
9491
* @return the expanded uri
9592
* @throws IllegalArgumentException if <code>uriVariables</code> is <code>null</code>; or if it does not contain
@@ -116,7 +113,6 @@ public URI expand(Map<String, String> uriVariables) {
116113
* System.out.println(template.expand("1", "42));
117114
* </pre>
118115
* will print: <blockquote><code>http://example.com/hotels/1/bookings/42</code></blockquote>
119-
*
120116
* @param uriVariableValues the array of uri variables
121117
* @return the expanded uri
122118
* @throws IllegalArgumentException if <code>uriVariables</code> is <code>null</code>; or if it does not contain
@@ -137,12 +133,11 @@ public URI expand(String... uriVariableValues) {
137133
m.appendReplacement(buffer, uriVariable);
138134
}
139135
m.appendTail(buffer);
140-
return URI.create(buffer.toString());
136+
return encodeUri(buffer.toString());
141137
}
142138

143139
/**
144140
* Indicates whether the given URI matches this template.
145-
*
146141
* @param uri the URI to match to
147142
* @return <code>true</code> if it matches; <code>false</code> otherwise
148143
*/
@@ -164,7 +159,6 @@ public boolean matches(String uri) {
164159
* System.out.println(template.match("http://example.com/hotels/1/bookings/42"));
165160
* </pre>
166161
* will print: <blockquote><code>{hotel=1, booking=42}</code></blockquote>
167-
*
168162
* @param uri the URI to match to
169163
* @return a map of variable values
170164
*/
@@ -182,6 +176,26 @@ public Map<String, String> match(String uri) {
182176
return result;
183177
}
184178

179+
private static URI encodeUri(String uri) {
180+
try {
181+
int idx = uri.indexOf(':');
182+
URI result;
183+
if (idx != -1) {
184+
String scheme = uri.substring(0, idx);
185+
String ssp = uri.substring(idx + 1);
186+
result = new URI(scheme, ssp, null);
187+
}
188+
else {
189+
result = new URI(null, null, uri, null);
190+
}
191+
return result;
192+
}
193+
catch (URISyntaxException e) {
194+
throw new IllegalArgumentException("Could not create URI from [" + uri + "]");
195+
}
196+
}
197+
198+
185199
@Override
186200
public String toString() {
187201
return uriTemplate;
@@ -218,17 +232,11 @@ private String encodeAndQuote(String fullPath, int start, int end) {
218232
if (start == end) {
219233
return "";
220234
}
221-
String result = fullPath.substring(start, end);
222-
try {
223-
URI uri = new URI(null, null, result, null);
224-
result = uri.toASCIIString();
225-
}
226-
catch (URISyntaxException e) {
227-
throw new IllegalArgumentException("Could not create URI from [" + fullPath + "]");
228-
}
235+
String result = encodeUri(fullPath.substring(start, end)).toASCIIString();
229236
return Pattern.quote(result);
230237
}
231238

239+
232240
private List<String> getVariableNames() {
233241
return Collections.unmodifiableList(variableNames);
234242
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ public void expandMapUnboundVariables() throws Exception {
8686
template.expand(uriVariables);
8787
}
8888

89+
@Test
90+
public void expandEncoded() throws Exception {
91+
template = new UriTemplate("http://example.com/hotel list/{hotel}");
92+
URI result = template.expand(Collections.singletonMap("hotel", "foo bar \u20AC"));
93+
assertEquals("Invalid expanded template", new URI("http", "//example.com/hotel list/foo bar \u20AC", null),
94+
result);
95+
assertEquals("Invalid expanded template", "http://example.com/hotel%20list/foo%20bar%20%E2%82%AC",
96+
result.toASCIIString());
97+
}
98+
8999
@Test
90100
public void matches() throws Exception {
91101
assertTrue("UriTemplate does not match", template.matches("http://example.com/hotels/1/bookings/42"));

0 commit comments

Comments
 (0)