Skip to content

Commit a363a22

Browse files
committed
Update URI links section after encoding changes
Issue: SPR-17039
1 parent 2bf7c18 commit a363a22

File tree

2 files changed

+71
-58
lines changed

2 files changed

+71
-58
lines changed

src/docs/asciidoc/web/web-uris.adoc

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
= UriComponents
44
[.small]#Spring MVC and Spring WebFlux#
55

6-
`UriComponents` is comparable to `java.net.URI`. However it comes with a dedicated
7-
`UriComponentsBuilder` and supports URI template variables:
6+
`UriComponentsBuilder` helps to build URI's from URI templates with variables:
87

98
[source,java,indent=0]
109
[subs="verbatim,quotes"]
@@ -13,26 +12,26 @@
1312
1413
UriComponents uriComponents = UriComponentsBuilder.fromUriString(uriTemplate) // <1>
1514
.queryParam("q", "{q}") // <2>
16-
.build(); // <3>
15+
.encode() // <3>
16+
.build(); // <4>
1717
18-
URI uri = uriComponents.expand("Westin", "123").encode().toUri(); // <4>
18+
URI uri = uriComponents.expand("Westin", "123").toUri(); // <5>
1919
----
2020
<1> Static factory method with a URI template.
21-
<2> Add or replace URI components.
22-
<3> Build `UriComponents`.
23-
<4> Expand URI variables, encode, and obtain the `URI`.
21+
<2> Add and/or replace URI components.
22+
<3> Request to have the URI template and URI variables encoded.
23+
<4> Build a `UriComponents`.
24+
<5> Expand variables, and obtain the `URI`.
2425

25-
The above can be done as a single chain and with a shortcut:
26+
The above can also be done in shorthand form:
2627

2728
[source,java,indent=0]
2829
[subs="verbatim,quotes"]
2930
----
30-
String uriTemplate = "http://example.com/hotels/{hotel}";
31-
3231
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
3332
.queryParam("q", "{q}")
34-
.buildAndExpand("Westin", "123")
3533
.encode()
34+
.buildAndExpand("Westin", "123")
3635
.toUri();
3736
----
3837

@@ -41,52 +40,48 @@ The above can be done as a single chain and with a shortcut:
4140
= UriBuilder
4241
[.small]#Spring MVC and Spring WebFlux#
4342

44-
<<web-uricomponents,UriComponentsBuilder>> is an implementation of `UriBuilder`. Together
45-
`UriBuilderFactory` and `UriBuilder` provide a pluggable mechanism for building a URI
46-
from a URI template, as well as a way to share common properties such as a base URI,
47-
encoding strategy, and others.
43+
<<web-uricomponents,UriComponentsBuilder>> implements `UriBuilder`. A `UriBuilder` in turn
44+
can be created with a `UriBuilderFactory`. Together `UriBuilderFactory` and `UriBuilder`
45+
provide a pluggable mechanism to build URIs from URI templates, based on shared
46+
configuration such as a base url, encoding preferences, and others.
4847

49-
Both the `RestTemplate` and the `WebClient` can be configured with a `UriBuilderFactory`
50-
in order to customize how URIs are created from URI templates. The default implementation
51-
relies on `UriComponentsBuilder` internally and provides options to configure a common
52-
base URI, an alternative encoding mode strategy, and more.
48+
The `RestTemplate` and the `WebClient` can be configured with a `UriBuilderFactory`
49+
to customize the preparation of URIs. `DefaultUriBuilderFactory` is a default
50+
implementation of `UriBuilderFactory` that uses `UriComponentsBuilder` internally and
51+
exposes shared configuration options.
5352

54-
An example of configuring the `RestTemplate`:
53+
`RestTemplate` example:
5554

5655
[source,java,indent=0]
5756
[subs="verbatim,quotes"]
5857
----
59-
String baseUrl = "http://example.com";
58+
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
59+
60+
String baseUrl = "http://example.org";
6061
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
62+
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VARIABLES);
6163
6264
RestTemplate restTemplate = new RestTemplate();
6365
restTemplate.setUriTemplateHandler(factory);
6466
----
6567

66-
Examples of configuring the `WebClient`:
68+
`WebClient` example:
6769

6870
[source,java,indent=0]
6971
[subs="verbatim,quotes"]
7072
----
71-
String baseUrl = "http://example.com";
73+
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
74+
75+
String baseUrl = "http://example.org";
7276
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
77+
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VARIABLES);
7378
74-
// Configure the UriBuilderFactory..
7579
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
76-
77-
// Or use shortcut on builder..
78-
WebClient client = WebClient.builder().baseUrl(baseUrl).build();
79-
80-
// Or use create shortcut...
81-
WebClient client = WebClient.create(baseUrl);
8280
----
8381

84-
You can also use `DefaultUriBuilderFactory` directly, as you would `UriComponentsBuilder`.
85-
The main difference is that `DefaultUriBuilderFactory` is stateful and can be re-used to
86-
prepare many URLs, sharing common configuration, such as a base URL, while
87-
`UriComponentsBuilder` is stateless and per URI.
88-
89-
An example of using the `DefaultUriBuilderFactory`:
82+
In addition `DefaultUriBuilderFactory` can also be used directly. It is similar to using
83+
`UriComponentsBuilder` but instead of static factory methods, it is an actual instance
84+
that holds configuration and preferences:
9085

9186
[source,java,indent=0]
9287
[subs="verbatim,quotes"]
@@ -96,47 +91,65 @@ An example of using the `DefaultUriBuilderFactory`:
9691
9792
URI uri = uriBuilderFactory.uriString("/hotels/{hotel}")
9893
.queryParam("q", "{q}")
99-
.build("Westin", "123"); // encoding strategy applied..
94+
.build("Westin", "123");
10095
----
10196

10297

10398
[[web-uri-encoding]]
10499
= URI Encoding
105100
[.small]#Spring MVC and Spring WebFlux#
106101

107-
By default `UriComponents` encodes only characters that are illegal within a given URI
108-
component, but not all characters with reserved meaning. More specifically `UriComponents`
109-
does the following:
102+
When using `UriComponentsBuilder` directly, this is the preferred way to encode:
110103

111-
. Expand URI variables.
112-
. Encode each URI component (path, query, etc) individually, by applying percent encoding
113-
to illegal characters such as non-US-ASCII characters as well as any characters that are
114-
illegal within the URI component, as per RFC 3986.
104+
[source,java,indent=0]
105+
[subs="verbatim,quotes"]
106+
----
107+
String uriTemplate = "http://example.com/hotels/{hotel}";
108+
109+
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
110+
.queryParam("q", "{q}")
111+
.encode()
112+
.buildAndexpand("Westin", "123")
113+
.toUri();
114+
----
115115

116-
This is comparable to the way the `java.net.URI` multi-argument constructor works and is
117-
described in the "Escaped octets, quotation, encoding, and decoding" section of its Javadoc.
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:
118118

119-
In some cases, you may want to ensure that expanded URI variables do not impact the
120-
structure and meaning of the URI. That means encoding not only illegal characters but also
121-
all characters with reserved meaning in a URI.
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.
122124

123-
The `WebClient` and the `RestTemplate` can be switched to a different encoding mode
124-
through the <<web-uribuilder,UriBuilderFactory>> strategy:
125+
The `WebClient` and the `RestTemplate` rely on a `UriBuilderFactory` to expand URI template
126+
and apply encoding. The `DefaultUriBuilderFactory` provides multiple encoding modes:
125127

126128
[source,java,indent=0]
127129
[subs="verbatim,quotes"]
128130
----
131+
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
132+
129133
String baseUrl = "http://example.com";
130134
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
131-
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
132-
133-
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
135+
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
134136
135137
RestTemplate restTemplate = new RestTemplate();
136138
restTemplate.setUriTemplateHandler(factory);
139+
140+
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
137141
----
138142

139-
Internally `DefaultUriBuilderFactory` delegates to `UriUtils.encode(String, Charset)` to
140-
encode each URI variable value prior to expanding it, effectively encoding both all
141-
non-US-ASCII characters, and characters with reserved meaning in a URI.
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.
146+
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`.
142153

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`.

src/docs/asciidoc/web/webmvc.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3112,7 +3112,7 @@ Javadoc for more details.
31123112
== URI Links
31133113
[.small]#<<web-reactive.adoc#mvc-uri-building,Same in Spring WebFlux>>#
31143114

3115-
This section describes various options available in the Spring Framework to prepare URIs.
3115+
This section describes various options available in the Spring Framework to work with URI's.
31163116

31173117

31183118

0 commit comments

Comments
 (0)