Spring 4 官方文档学习(十一)Web MVC 框架之URI Builder

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-uri-building

 

Spring MVC 提供了一种机制,可以构造和编码URI -- 使用UriComponentsBuilder和UriComponents。

例:

UriComponents uriComponents = UriComponentsBuilder.fromUriString(
        "http://example.com/hotels/{hotel}/bookings/{booking}").build();

URI uri = uriComponents.expand("42", "21").encode().toUri();

嗯,expand()是用于替换所有的模板变量,encode默认使用UTF8编码。

注意,UriComponents是不可变的,expand()和encode()都是返回新的实例。

 

你还可以这样做:

UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build()
        .expand("42", "21")
        .encode();

 

在Servlet环境中,使用子类ServletUriComponentsBuilder提供的静态工厂方法可以从一个Servlet request中获取有用的URI信息:

HttpServletRequest request = ...

// Re-use host, scheme, port, path and query string
// Replace the "accountId" query param

ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromRequest(request)
        .replaceQueryParam("accountId", "{id}").build()
        .expand("123")
        .encode();

或者,你还可以选择复制这些可用信息的一个子集:

// Re-use host, port and context path
// Append "/accounts" to the path

ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromContextPath(request)
        .path("/accounts").build()

或者,当DispatcherServlet按名字被映射时(如 /main/*),你也可以拥有servlet映射的字面部分(???什么鬼):

// Re-use host, port, context path
// Append the literal part of the servlet mapping to the path
// Append "/accounts" to the path

ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromServletMapping(request)
        .path("/accounts").build()

 

1、构造连接到controllers和methods的URIs

Spring MVC也提供了一种机制,以构造到controller methods的连接。例如,当给定以下controller时:

@Controller
@RequestMapping("/hotels/{hotel}")
public class BookingController {

    @GetMapping("/bookings/{booking}")
    public String getBooking(@PathVariable Long booking) {

    // ...
    }
}

你可以通过名字引用该方法,来准备一个连接:

UriComponents uriComponents = MvcUriComponentsBuilder
    .fromMethodName(BookingController.class, "getBooking", 21).buildAndExpand(42);

URI uri = uriComponents.encode().toUri();

中上面的例子中,我们提供了实际的方法参数值,21。更进一步,我们还提供了42以填补剩余的URI变量,例如”hotel”。如果该方法拥有更多参数,你可以为那些不需要出现在URI中的参数提供null。一般来说,只有@PathVariable和@RequestParam参数与构建URL相关。

 

还有其他方式来使用MvcUriComponentsBuilder。例如,你可以使用一种技术族来模拟测试 -- 通过代理以避免通过名字引用controller name (下例假定已静态导入了MvcUriComponentsBuilder.on):

UriComponents uriComponents = MvcUriComponentsBuilder
    .fromMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);

URI uri = uriComponents.encode().toUri();

上例中,使用了MvcUriComponentsBuilder中的静态方法。在内部,他们依赖于ServletUriComponentsBuilder 来准备一个base URL -- 基于当前request的scheme、host、port、context path以及 servlet path。大多数时候这样很有效,然而,有时候也是不够的。例如,你可能在request的context之外(例如,准备links的批处理),或者你需要插入一个path前缀 (例如,locale前缀 -- 从request path中被移除过的,且需要被重新插入连接)。

 

这些情况下,你可以使用静态的”fromXxx”方法的重载 -- 那些接收一个UriComponentsBuilder的方法,来使用base URL。或者,你可以使用一个base URL来创建MvcUriComponentsBuilder的实例,然后使用该实例的”withXxx”方法。 例如:

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();

 

2、从views构建连接到controllers和methods的URIs

你还可以从views(如JSP、Thymeleaf、FreeMarker)构建到注解controllers的连接。使用MvcUriComponentsBuilder的fromMappingName(..)方法即可。

 

每个@RequestMapping都被给定了一个默认的名字 -- 基于class的大写字母和全方法名。例如,FooController中的getFoo方法,被赋予了名字”FC#getFoo”。这种策略可以被替换或定制--通过创建一个HandlerMethodMappingNamingStrategy实例,再将其插入你的RequestMappingHandlerMapping即可。默认的策略实现还要看一下@RequestMapping的name attribute,如果有则使用。这意味着,如果默认被赋予的映射名字与其他的发生了冲突(例如,重载的方法),你可以给该@RequestMapping显式的赋予一个name。

被赋予的请求映射名字,在启动时会被以TRACE级别记录。

Spring JSP tag库 提供了一个功能,叫做mvcUrl,可被用于基于该机制准备到controller methods的连接。

例如,当给定以下controller时:

@RequestMapping("/people/{id}/addresses")
public class PersonAddressController {

    @RequestMapping("/{country}")
    public HttpEntity getAddress(@PathVariable String country) { ... }
}

你可以准备一个连接--从JSP中,如下:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
...
<a href="${s:mvcUrl('PAC#getAddress').arg(0,'US').buildAndExpand('123')}">Get Address</a>

上面的例子依赖于Spring 标签库(如 META-INF/spring.tld)中声明的mvcUrl JSP功能。

 

-- 好吧, 看完了,明白功能,但是,干嘛用的???测试吗?还是类似HttpClient或者RestTemplate的功能?

posted on 2016-12-04 20:01  LarryZeal  阅读(8851)  评论(2编辑  收藏  举报

导航