Mastering Spring's UriComponentsBuilder: Build and Encode URIs Efficiently
This guide demonstrates how to use Spring's UriComponentsBuilder and related classes—UriBuilderFactory, ServletUriComponentsBuilder, and MvcUriComponentsBuilder—to construct, encode, and link URIs in various scenarios, providing clear code examples for each step, including handling templates, query parameters, and servlet contexts.
Environment: Spring 2.7.16
1. UriComponents
UriComponentsBuilder helps build a URI from a template with variables. Example:
<code>UriComponents uriComponents = UriComponentsBuilder
.fromUriString("http://www.pack.com/users/{name}")
.queryParam("q", "{q}")
.encode()
.build();
URI uri = uriComponents.expand("name", "pack").toUri();
System.out.println(uri);
</code>Output:
<code>http://www.pack.com/hotels/name?q=pack</code>You can also build directly with a URI:
<code>URI uri = UriComponentsBuilder
.fromUriString("http://www.pack.com/users/{name}")
.queryParam("q", "{q}")
.build("name", "pack");
System.out.println(uri);
</code>Or use a compact template form:
<code>URI uri = UriComponentsBuilder
.fromUriString("http://www.pack.com/users/{name}?q={q}")
.build("name", "pack");
</code>2. UriBuilder
UriComponentsBuilder implements UriBuilder. UriBuilderFactory can create UriBuilder instances, allowing shared configuration (base URL, encoding mode, etc.) for RestTemplate and WebClient. DefaultUriBuilderFactory is the default implementation.
Example with RestTemplate:
<code>String baseUrl = "http://www.pack.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);
</code>Example with WebClient:
<code>DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
WebClient client = WebClient.builder()
.uriBuilderFactory(factory)
.build();
</code>Creating a URI directly:
<code>DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);
URI uri = uriBuilderFactory.uriString("/users/{name}")
.queryParam("q", "pack")
.build("name", "pack");
System.out.println(uri);
</code>Output:
<code>http://www.pack.com/users/name?q=pack</code>3. URI Encoding
UriComponentsBuilder provides two encoding options:
UriComponentsBuilder#encode(): pre‑encodes the URI template and then strictly encodes variables during expansion.
UriComponents#encode(): encodes the URI components after variable expansion.
Usually the first option yields the expected result, while the second is useful when variables intentionally contain reserved characters or when no expansion occurs.
<code>URI uri = UriComponentsBuilder.fromPath("/users list/{name}")
.queryParam("q", "{q}")
.encode()
.buildAndExpand("name", "pack")
.toUri();
System.out.println(uri);
</code>Output:
<code>/users%20list/name?q=pack</code>Simplified version:
<code>URI uri = UriComponentsBuilder.fromPath("/users list/{name}")
.queryParam("q", "{q}")
.build("name", "pack");
</code>Full template example:
<code>URI uri = UriComponentsBuilder.fromUriString("/users list/{name}?q={q}")
.build("name", "pack");
</code>4. Servlet Request
ServletUriComponentsBuilder can create a URI relative to the current request:
<code>MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/users");
URI uri = ServletUriComponentsBuilder.fromRequest(request)
.replaceQueryParam("id", "{id}")
.build("666");
System.out.println(uri);
</code>Output:
<code>http://localhost/users?id=666</code>You can also build a URI relative to the context path:
<code>URI uri = ServletUriComponentsBuilder.fromContextPath(request)
.path("/users")
.build()
.toUri();
</code>5. Linking to a Controller
Spring MVC’s MvcUriComponentsBuilder can generate a link to a controller method:
<code>MockHttpServletRequest request = new MockHttpServletRequest();
ServletRequestAttributes requestAttribute = new ServletRequestAttributes(request);
RequestContextHolder.setRequestAttributes(requestAttribute);
UriComponents uriComponents = MvcUriComponentsBuilder
.fromMethodName(UserController.class, "queryById", 666L)
.buildAndExpand();
URI uri = uriComponents.encode().toUri();
System.out.println(uri);
</code>Output:
<code>http://localhost/users/666</code>That concludes the article.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.