URI在网络申请中必不可少,Spring提供了一些工具类用于解析或者生成URL,比方依据参数生成GET的URL等。本文会对Spring MVC中的URI工具进行介绍,本文次要参考Spring官网文档。
<!--more-->
工具类UriComponents
UriComponentsBuilder能够用于依据URL和参数来构建门路,比方咱们须要一个带GET参数的URL,通常状况下咱们须要本人去拼接URL,增加"&"和"?等参数"。UriComponentsBuilder提供一种更简介的办法去构建URL:
UriComponents uriComponents = UriComponentsBuilder .fromUriString("https://example.com/hotels/{hotel}") .queryParam("q", "{q}") .encode() .build(); // https://example.com/hotels/Westin?q=123URI uri = uriComponents.expand("Westin", "123").toUri();
下面的两条语句也能够合并到一个Build链中,用如下形式达到同样的目标:
URI uri = UriComponentsBuilder .fromUriString("https://example.com/hotels/{hotel}") .queryParam("q", "{q}") .encode() .buildAndExpand("Westin", "123") .toUri();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");
接口UriBuilder
UriComponentsBuilder实现了UriBuilder接口,该接口的次要性能就是构建Uri。Spring中能够通过UriBuilderFactory获取UriBuilder的实例。咱们平时应用httpClient类如Spring的RestTemplate,并不需要本人拼接Uri,只须要输出参数组件会主动拼接Url。对于过Spring的RestTemplate,其外部应用的Url组件就是UriBuilderFactory。
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;String baseUrl = "https://example.org";DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);RestTemplate restTemplate = new RestTemplate();restTemplate.setUriTemplateHandler(factory);
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;String baseUrl = "https://example.org";DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
String baseUrl = "https://example.com";DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);URI uri = uriBuilderFactory.uriString("/hotels/{hotel}") .queryParam("q", "{q}") .build("Westin", "123");
Url的编码
UriComponentsBuilder组件提供了两种类型的编码方式:
- UriComponentsBuilder#encode():对Url模板和参数别离进行编码之后进行拼接。
- UriComponents#encode():对拼接后的Url进行编码操作。
大多数状况下适宜应用UriComponentsBuilder#encode(),因为它将参数独自进行了编码。然而如果你须要在编码中保留特殊字符,那么最好应用第二种编码方式。
URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}") .queryParam("q", "{q}") .encode() .buildAndExpand("New York", "foo+bar") .toUri();// Result is "/hotel%20list/New%20York?q=foo%2Bbar"
Servlet Uri构建
Spring提供了另一个Uri组件ServletUriComponentsBuilder,该组件能够基于Servlet申请构建新的Uri:
HttpServletRequest request = ...// Re-uses host, scheme, port, path and query string...ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromRequest(request) .replaceQueryParam("accountId", "{id}").build() .expand("123") .encode();// Re-uses host, port and context path...ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromContextPath(request).path("/accounts").build()// Re-uses host, port, context path, and Servlet prefix...ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromServletMapping(request).path("/accounts").build()
Controller Uri
咱们晓得Spring中能够通过@RequestMapping把一个申请映射到Controller的办法上,那么咱们如何获取到Controller办法的申请门路呢?
@Controller@RequestMapping("/hotels/{hotel}")public class BookingController { @GetMapping("/bookings/{booking}") public ModelAndView getBooking(@PathVariable Long booking) { // ... }}
Spring 提供了MvcUriComponentsBuilder工具获取Controller办法对应的门路,其应用示例如下所示:
// 21:指明参数的类型, 42:新的参数类型. UriComponents uriComponents = MvcUriComponentsBuilder .fromMethodName(BookingController.class, "getBooking", 21).buildAndExpand(42);URI uri = uriComponents.encode().toUri();UriComponents uriComponents = MvcUriComponentsBuilder .fromMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);URI uri = uriComponents.encode().toUri();
Controller办法应该是非Final的,否则Spring可能会获取不到配置的门路信息。
MvcUriComponentsBuilder 还反对指定Context,如域名等信息,示例如下所示:
UriComponentsBuilder base = ServletUriComponentsBuilder.fromCurrentContextPath().path("/en");MvcUriComponentsBuilder builder = MvcUriComponentsBuilder.relativeTo(base);builder.withMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);URI uri = uriComponents.encode().toUri();
视图中的URL
在Thymeleaf、FreeMarker和JSP等视图组件中,咱们能够通过视图URL组件去拼接URL,示例如下:
@RequestMapping("/people/{id}/addresses")public class PersonAddressController { @RequestMapping("/{country}") public HttpEntity<PersonAddress> getAddress(@PathVariable String country) { ... }}
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>...<a href="${s:mvcUrl('PAC#getAddress').arg(0,'US').buildAndExpand('123')}">Get Address</a>
本文最先公布至微信公众号,版权所有,禁止转载!