@@ -99,37 +99,47 @@ that holds configuration and preferences:
99
99
= URI Encoding
100
100
[.small]#Spring MVC and Spring WebFlux#
101
101
102
- When using `UriComponentsBuilder` directly, this is the preferred way to encode:
102
+ `UriComponentsBuilder` exposes encoding options at 2 levels:
103
+
104
+ . {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()] -
105
+ pre-encodes the URI template first, then strictly encodes URI variables when expanded.
106
+ . {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()] -
107
+ encodes URI components _after_ URI variables are expanded.
108
+
109
+ Both options replace non-ASCII and illegal characters with escaped octets, however option
110
+ 1 also replaces characters with reserved meaning that appear in URI variables.
111
+
112
+ [TIP]
113
+ ====
114
+ Consider ";" which is legal in a path but has reserved meaning. Option 1 replaces
115
+ ";" with "%3B" in URI variables but not in the URI template. By contrast, option 2 never
116
+ replaces ";" since it is a legal character in a path.
117
+ ====
118
+
119
+ For most cases option 1 is likely to give the expected result because in treats URI
120
+ variables as opaque data to be fully encoded, while option 2 is useful only if
121
+ intentionally expanding URI variables that contain reserved characters.
122
+
123
+ Example usage using option 1:
103
124
104
125
[source,java,indent=0]
105
126
[subs="verbatim,quotes"]
106
127
----
107
- String uriTemplate = "http://example.com/hotels/{hotel}";
108
-
109
- URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
128
+ UriComponentsBuilder.fromPath("/hotel list/{city}")
110
129
.queryParam("q", "{q}")
111
130
.encode()
112
- .buildAndexpand("Westin", "123")
113
- .toUri();
114
- ----
115
-
116
- First, the URI template is encoded when `UriComponents` is built. Then URI variables are
117
- encoded separately when expanded. The following rules apply to each:
131
+ .buildAndexpand("New York", "foo+bar")
132
+ .toUriString();
118
133
119
- * The URI template is encoded by quoting _only_ characters that are illegal within a
120
- given URI component type. For example, spaces are illegal in a path and therefore encoded.
121
- * URI variables are encoded more strictly, by quoting both illegal characters and also
122
- characters with reserved meaning. For example ";" is legal in a path but has reserved
123
- meaning (as a path parameter separator) and therefore encoded.
134
+ // Result is "/hotel%20list/New%20York?foo%2Bbar"
135
+ ----
124
136
125
- The `WebClient` and the `RestTemplate` rely on a `UriBuilderFactory` to expand URI template
126
- and apply encoding. The `DefaultUriBuilderFactory` provides multiple encoding modes :
137
+ The `WebClient` and the `RestTemplate` expand and encode URI templates internally through
138
+ the `UriBuilderFactory` strategy. Both can be configured wiht a custom instance :
127
139
128
140
[source,java,indent=0]
129
141
[subs="verbatim,quotes"]
130
142
----
131
- // import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
132
-
133
143
String baseUrl = "http://example.com";
134
144
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
135
145
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
@@ -140,16 +150,17 @@ and apply encoding. The `DefaultUriBuilderFactory` provides multiple encoding mo
140
150
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
141
151
----
142
152
143
- Internally `DefaultUriBuilderFactory` uses `UriComponentsBuilder`. The
144
- `EncodingMode.TEMPLATE_AND_VALUES` corresponds to the `UriComponentsBuilder` encoding
145
- example shown earlier. It is the preferred mode.
153
+ The `DefaultUriBuilderFactory` implementation shown above uses `UriComponentsBuilder`
154
+ internally. The approach to encoding is controlled through one of the encoding modes
155
+ listed below:
146
156
147
- Out of the box, `RestTemplate` is configured with `EncodingMode.URI_COMPONENTS` which has
148
- been used historically and still is the default for backwards compatibility. It works by
149
- expanding URI variables first, and then encoding the expanded URI component values,
150
- quoting _only_ illegal characters within a given URI component type, but not all
151
- characters with reserved meaning. As of 5.0.8, you can switch to the preferred
152
- `EncodingMode.TEMPLATE_AND_VALUES` .
157
+ * `TEMPLATE_AND_VALUES` -- uses `UriComponentsBuilder#encode()`, corresponding to option
158
+ 1 above, to pre-encode the URI template and strictly encode URI variables when expanded.
159
+ * `VALUES_ONLY` -- variant of `TEMPLATE_AND_VALUES` that does not encode the URI template.
160
+ * `URI_COMPONENTS` -- uses `UriComponents#encode()`, corresponding to option 2 above, to
161
+ encode URI component value _after_ URI variables are expanded.
162
+ * `NONE` -- no encoding is applied .
153
163
154
- `WebClient` is configured with `EncodingMode.TEMPLATE_AND_VALUES` by default starting in
155
- 5.1, In 5.0.x however the default remains `EncodingMode.URI_COMPONENTS`.
164
+ Out of the box the `RestTemplate` uses `EncodingMode.URI_COMPONENTS` for historic reasons
165
+ and for backwards compatibility. The `WebClient` uses `EncodingMode.TEMPLATE_AND_VALUES`
166
+ starting in 5.1, and `EncodingMode.URI_COMPONENTS` in 5.0.x.
0 commit comments