2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
[[web-uricomponents]]
|
|
|
|
= UriComponents
|
2018-02-17 01:58:01 +08:00
|
|
|
[.small]#Spring MVC and Spring WebFlux#
|
2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
`UriComponents` is comparable to `java.net.URI`. However it comes with a dedicated
|
2018-02-16 21:25:13 +08:00
|
|
|
`UriComponentsBuilder` and supports URI template variables:
|
2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
String uriTemplate = "http://example.com/hotels/{hotel}";
|
|
|
|
|
|
|
|
UriComponents uriComponents = UriComponentsBuilder.fromUriString(uriTemplate) // <1>
|
|
|
|
.queryParam("q", "{q}") // <2>
|
|
|
|
.build(); // <3>
|
|
|
|
|
|
|
|
URI uri = uriComponents.expand("Westin", "123").encode().toUri(); // <4>
|
|
|
|
----
|
|
|
|
<1> Static factory method with a URI template.
|
|
|
|
<2> Add or replace URI components.
|
|
|
|
<3> Build `UriComponents`.
|
|
|
|
<4> Expand URI variables, encode, and obtain the `URI`.
|
|
|
|
|
2018-02-16 21:25:13 +08:00
|
|
|
The above can be done as a single chain and with a shortcut:
|
2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
String uriTemplate = "http://example.com/hotels/{hotel}";
|
|
|
|
|
|
|
|
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
|
|
|
|
.queryParam("q", "{q}")
|
|
|
|
.buildAndExpand("Westin", "123")
|
|
|
|
.encode()
|
|
|
|
.toUri();
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
[[web-uribuilder]]
|
|
|
|
= UriBuilder
|
2018-02-17 01:58:01 +08:00
|
|
|
[.small]#Spring MVC and Spring WebFlux#
|
2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
<<web-uricomponents,UriComponentsBuilder>> is an implementation of `UriBuilder`. Together
|
|
|
|
`UriBuilderFactory` and `UriBuilder` provide a pluggable mechanism for building a URI
|
|
|
|
from a URI template, as well as a way to share common properties such as a base URI,
|
|
|
|
encoding strategy, and others.
|
|
|
|
|
2018-02-16 21:25:13 +08:00
|
|
|
Both the `RestTemplate` and the `WebClient` can be configured with a `UriBuilderFactory`
|
2018-02-16 12:25:52 +08:00
|
|
|
in order to customize how URIs are created from URI templates. The default implementation
|
2018-02-16 21:25:13 +08:00
|
|
|
relies on `UriComponentsBuilder` internally and provides options to configure a common
|
|
|
|
base URI, an alternative encoding mode strategy, and more.
|
2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
An example of configuring the `RestTemplate`:
|
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
String baseUrl = "http://example.com";
|
|
|
|
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
|
|
|
|
|
|
|
|
RestTemplate restTemplate = new RestTemplate();
|
|
|
|
restTemplate.setUriTemplateHandler(factory);
|
|
|
|
----
|
|
|
|
|
|
|
|
Examples of configuring the `WebClient`:
|
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
String baseUrl = "http://example.com";
|
|
|
|
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
|
|
|
|
|
|
|
|
// Configure the UriBuilderFactory..
|
|
|
|
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
|
|
|
|
|
|
|
|
// Or use shortcut on builder..
|
|
|
|
WebClient client = WebClient.builder().baseUrl(baseUrl).build();
|
|
|
|
|
|
|
|
// Or use create shortcut...
|
|
|
|
WebClient client = WebClient.create(baseUrl);
|
|
|
|
----
|
|
|
|
|
|
|
|
You can also use `DefaultUriBuilderFactory` directly, as you would `UriComponentsBuilder`.
|
|
|
|
The main difference is that `DefaultUriBuilderFactory` is stateful and can be re-used to
|
|
|
|
prepare many URLs, sharing common configuration, such as a base URL, while
|
|
|
|
`UriComponentsBuilder` is stateless and per URI.
|
|
|
|
|
|
|
|
An example of using the `DefaultUriBuilderFactory`:
|
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
String baseUrl = "http://example.com";
|
|
|
|
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);
|
|
|
|
|
|
|
|
URI uri = uriBuilderFactory.uriString("/hotels/{hotel}")
|
|
|
|
.queryParam("q", "{q}")
|
|
|
|
.build("Westin", "123"); // encoding strategy applied..
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
[[web-uri-encoding]]
|
|
|
|
= URI Encoding
|
2018-02-17 01:58:01 +08:00
|
|
|
[.small]#Spring MVC and Spring WebFlux#
|
2018-02-16 12:25:52 +08:00
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
By default `UriComponents` encodes only characters that are illegal within a given URI
|
|
|
|
component, but not all characters with reserved meaning. More specifically `UriComponents`
|
|
|
|
does the following:
|
2018-02-16 12:25:52 +08:00
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
. Expand URI variables.
|
|
|
|
. Encode each URI component (path, query, etc) individually, by applying percent encoding
|
|
|
|
to illegal characters such as non-US-ASCII characters as well as any characters that are
|
|
|
|
illegal within the URI component, as per RFC 3986.
|
2018-02-16 12:25:52 +08:00
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
This is comparable to the way the `java.net.URI` multi-argument constructor works and is
|
|
|
|
described in the "Escaped octets, quotation, encoding, and decoding" section of its Javadoc.
|
2018-02-16 12:25:52 +08:00
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
In some cases, you may want to ensure that expanded URI variables do not impact the
|
|
|
|
structure and meaning of the URI. That means encoding not only illegal characters but also
|
|
|
|
all characters with reserved meaning in a URI.
|
2018-02-16 12:25:52 +08:00
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
The `WebClient` and the `RestTemplate` can be switched to a different encoding mode
|
|
|
|
through the <<web-uribuilder,UriBuilderFactory>> strategy:
|
2018-02-16 12:25:52 +08:00
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
[subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
String baseUrl = "http://example.com";
|
|
|
|
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
|
|
|
|
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
|
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
|
|
|
|
|
|
|
|
RestTemplate restTemplate = new RestTemplate();
|
|
|
|
restTemplate.setUriTemplateHandler(factory);
|
2018-02-16 12:25:52 +08:00
|
|
|
----
|
|
|
|
|
2018-06-12 22:14:35 +08:00
|
|
|
Internally `DefaultUriBuilderFactory` delegates to `UriUtils.encode(String, Charset)` to
|
|
|
|
encode each URI variable value prior to expanding it, effectively encoding both all
|
|
|
|
non-US-ASCII characters, and characters with reserved meaning in a URI.
|
2018-02-16 12:25:52 +08:00
|
|
|
|