前言
Spring 提供了许多 URI 操作工具类,方便我们对 URI 进行处理。
UriComponents
UriComponentsBuilder 使用 URI 模版和变量来构建 URI,避免通过字符串拼接构建 URI。
UriComponents uriComponents = UriComponentsBuilder
.fromUriString("https://example.com/hotels/{hotel}")
.queryParam("q", "{q}") // 添加参数
.encode()
.build(); // 构建
// 填充变量并获取 URI 对象
URI uri = uriComponents.expand("Westin", "123").toUri();
也可以在一条语句中直接构建生成。
URI uri = UriComponentsBuilder
.fromUriString("https://example.com/hotels/{hotel}")
.queryParam("q", "{q}")
.encode()
.buildAndExpand("Westin", "123")
.toUri();
// 更简化的版本,自动 encoding
URI uri = UriComponentsBuilder
.fromUriString("https://example.com/hotels/{hotel}")
.queryParam("q", "{q}")
.build("Westin", "123");
// 合并请求参数
URI uri = UriComponentsBuilder
.fromUriString("https://example.com/hotels/{hotel}?q={q}")
.build("Westin", "123");
UriBuilderFactory
UriComponentsBuilder 实现了 UriBuilder 接口,而要创建 UriBuilder 接口的实例,也可以通过 UriBuilderFactory 接口。DefaultUriBuilderFactory 是 UriBuilderFactory 的一个默认的实现类。
我们可以直接使用这个工厂类来创建 UriComponentsBuilder。
String baseUrl = "https://example.com";
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);
URI uri = uriBuilderFactory.uriString("/hotels/{hotel}")
.queryParam("q", "{q}")
.build("Westin", "123");
但更常用的是和 HTTP 客户端结合使用,可以和 RestTemplate 或 WebClient 等 Spring 提供的 HTTP 客户端配合使用,来方便地配置 URI。
下面是 RestTemplate 的使用例子:
String baseUrl = "https://example.org";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);
下面是 WebClient 的使用例子:
String baseUrl = "https://example.org";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
ServletUriComponentsBuilder
可以使用 ServletUriComponentsBuilder 工具类创建基于当前请求 URI 的相对请求。
// 获取当前请求对象
HttpServletRequest request = ...
// 复用了 scheme, host, port, path, query string...
URI uri = ServletUriComponentsBuilder.fromRequest(request)
.replaceQueryParam("accountId", "{id}")
.build("123");
// 复用了 scheme, host, port, context path...
URI uri = ServletUriComponentsBuilder.fromContextPath(request)
.path("/accounts")
.build()
.toUri();
// 复用了 scheme, host, port, context path, Servlet mapping prefix...
URI uri = ServletUriComponentsBuilder.fromServletMapping(request)
.path("/accounts")
.build()
.toUri();
MvcUriComponentsBuilder
MvcUriComponentsBuilder 可以从控制器类来创建请求 URI。
假设我们有如下的控制器。
@Controller
@RequestMapping("/hotels/{hotel}")
public class BookingController {
@GetMapping("/bookings/{booking}")
public ModelAndView getBooking(@PathVariable Long booking) {
// ...
}
}
我们通过如下的方法创建对应的请求 URI。
// 21 是方法的参数,而 42 是路径参数 hotel
UriComponents uriComponents = MvcUriComponentsBuilder
.fromMethodName(BookingController.class, "getBooking", 21).buildAndExpand(42);
URI uri = uriComponents.encode().toUri();
本文主要介绍了 Spring 提供的一些创建 URI 的工具类,想了解更多 Spring Web 的内容,可参考我写的 Spring Web 速查指南。