Skip to content

Commit 2bf7c18

Browse files
committed
Add TEMPLATE_AND_VALUES mode to DefaultUriBuilderFactory
Issue: SPR-17039
1 parent 9458186 commit 2bf7c18

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

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

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.web.util;
1818

1919
import java.net.URI;
20-
import java.nio.charset.Charset;
2120
import java.util.Collections;
2221
import java.util.HashMap;
2322
import java.util.Map;
@@ -49,16 +48,33 @@ public class DefaultUriBuilderFactory implements UriBuilderFactory {
4948
public enum EncodingMode {
5049

5150
/**
52-
* Apply strict encoding to URI variables at the time of expanding,
53-
* quoting both illegal characters and characters with reserved meaning
54-
* via {@link UriUtils#encode(String, Charset)}.
51+
* Encode the URI template first, and URI variables later when expanded,
52+
* applying the following to each:
53+
* <ul>
54+
* <li>URI template is encoded by quoting <em>only</em> illegal
55+
* characters within a given URI component type.
56+
* <li>URI variables are encoded strictly, by quoting both illegal
57+
* characters and characters with reserved meaning.
58+
* </ul>
59+
* <p>For most cases this should be the preferred encoding mode.
60+
* @since 5.0.8
61+
* @see UriComponentsBuilder#encode()
62+
*/
63+
TEMPLATE_AND_VALUES,
64+
65+
/**
66+
* Encode only URI variables strictly quoting both illegal characters
67+
* and characters with reserved meaning.
68+
* @see UriUtils#encodeUriVariables(Object...)
69+
* @see UriUtils#encodeUriVariables(Map)
5570
*/
5671
VALUES_ONLY,
5772

5873
/**
59-
* Expand URI variables first, then encode the resulting URI component
74+
* Expand URI variables first, and then encode the expanded URI component
6075
* values, quoting <em>only</em> illegal characters within a given URI
6176
* component type, but not all characters with reserved meaning.
77+
* @see UriComponents#encode()
6278
*/
6379
URI_COMPONENT,
6480

@@ -110,7 +126,7 @@ public DefaultUriBuilderFactory(UriComponentsBuilder baseUri) {
110126

111127

112128
/**
113-
* Specify the {@link EncodingMode EncodingMode} to use when building URIs.
129+
* Specify the {@link EncodingMode EncodingMode} to use to encode URIs.
114130
* <p>By default set to
115131
* {@link EncodingMode#URI_COMPONENT EncodingMode.URI_COMPONENT}.
116132
* @param encodingMode the encoding mode to use
@@ -216,13 +232,17 @@ private UriComponentsBuilder initUriComponentsBuilder(String uriTemplate) {
216232
result = UriComponentsBuilder.fromUriString(uriTemplate);
217233
}
218234

235+
if (encodingMode.equals(EncodingMode.TEMPLATE_AND_VALUES)) {
236+
result.encode();
237+
}
238+
219239
parsePathIfNecessary(result);
220240

221241
return result;
222242
}
223243

224244
private void parsePathIfNecessary(UriComponentsBuilder result) {
225-
if (shouldParsePath() && encodingMode.equals(EncodingMode.URI_COMPONENT)) {
245+
if (parsePath && encodingMode.equals(EncodingMode.URI_COMPONENT)) {
226246
UriComponents uric = result.build();
227247
String path = uric.getPath();
228248
result.replacePath(null);

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ public void defaultUriVarsSpr14147() {
9797
assertEquals("https://api.example.com:443/v42/customers/123", uri.toString());
9898
}
9999

100+
@Test
101+
public void encodeTemplateAndValues() {
102+
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
103+
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
104+
UriBuilder uriBuilder = factory.uriString("/hotel list/{city} specials?q={value}");
105+
106+
String expected = "/hotel%20list/Z%C3%BCrich%20specials?q=a%2Bb";
107+
108+
Map<String, Object> vars = new HashMap<>();
109+
vars.put("city", "Z\u00fcrich");
110+
vars.put("value", "a+b");
111+
112+
assertEquals(expected, uriBuilder.build("Z\u00fcrich", "a+b").toString());
113+
assertEquals(expected, uriBuilder.build(vars).toString());
114+
}
115+
100116
@Test
101117
public void encodingValuesOnly() {
102118
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();

0 commit comments

Comments
 (0)