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

142 lines
4.5 KiB
Plaintext

[[web-uricomponents]]
= UriComponents
`UriComponents` is comparable to `java.net.URI`. However it comes with a dedicated
`UriComponentsBuilder` and supports URI template variables:
[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`.
The above can be done as a single chain and with a shortcut:
[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
<<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.
Both the `RestTemplate` and the `WebClient` can be configured with a `UriBuilderFactory`
in order to customize how URIs are created from URI templates. The default implementation
relies on `UriComponentsBuilder` internally and provides options to configure a common
base URI, an alternative encoding mode strategy, and more.
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
The default way of encoding URIs in `UriComponents` works as follows:
. URI variables are expanded.
. URI components are encoded individually.
For each URI component, percent encoding is applied to all illegal characters, which
includes non-US-ASCII characters, and other characters that are illegal within a given
URI component type, as defined in RFC 3986.
[TIP]
====
The encoding in `UriComponents` is comparable to the multi-argument constructor of
`java.net.URI`, as described in the "Escaped octets, quotation, encoding, and decoding"
section of its class-level Javadoc.
====
This default encoding strategy *does not* encode all characters with reserved meaning,
but rather only the ones that are illegal within a given URI component. If this is not
what you expect you can use an alternative.
When using <<web-uribuilder,DefaultUriBuilderFactory>> you can switch to an alternative
encoding strategy:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
String baseUrl = "http://example.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
// ...
----
The above encoding strategy applies `UriUtils.encode(String, Charset)` to each URI
variable value prior to expanding it. Effectively it encodes all characters with reserved
meaning, therefore ensuring that expanded URI variables do not have any impact on the
structure or meaning of the URI.