
[[web-uricomponents]]
= UriComponents
[.small]#Spring MVC and Spring WebFlux#

`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
[.small]#Spring MVC and Spring WebFlux#

<<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
[.small]#Spring MVC and Spring WebFlux#

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:

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

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.

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.

The `WebClient` and the `RestTemplate` can be switched to a different encoding mode
through the <<web-uribuilder,UriBuilderFactory>> strategy:

[source,java,indent=0]
[subs="verbatim,quotes"]
----
	String baseUrl = "http://example.com";
	DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
	factory.setEncodingMode(EncodingMode.VALUES_ONLY);

	WebClient client = WebClient.builder().uriBuilderFactory(factory).build();

	RestTemplate restTemplate = new RestTemplate();
	restTemplate.setUriTemplateHandler(factory);
----

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.

