Spring4.x官方参考文档中文版——第21章 Web MVC框架(20)

21.7 URI的组建

       Spring MVC提供了一种机制,可以使用UriComponentsBuilder和UriComponents来组建并编码URI。

       如下例所示,你能扩展并编码一个URI模板的字符串:

UriComponents uriComponents =UriComponentsBuilder.fromUriString(
       "http://example.com/hotels/{hotel}/bookings/{booking}").build();
 
URI uri = uriComponents.expand("42", "21").encode().toUri();

       注意,UriComponents是不可变的,而expand()和encode()操作,在必要的时候,会返回新的实例。

       你也可以使用独立的URI组件来扩展并编码URI:

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

       在Servlet环境下,ServletUriComponentBuilder的子类提供了一个静态工厂方法,这个方法可以从Servlet请求中,复制有效的URL信息。如下:

HttpServletRequest request = ...
 
// 重用原request中的host,scheme格式,端口,路径和查询参数的字符串
// 替换掉"accountId" 的查询参数值
 
ServletUriComponentsBuilder ucb =ServletUriComponentsBuilder.fromRequest(request)
       .replaceQueryParam("accountId", "{id}").build()
       .expand("123")
       .encode();

       此外,你也可以选择拷贝可用信息中的一部分,并追加到context路径后面:

// 重用host,port(端口)和context路径
// 把"/accounts"追加到路径后面
 
ServletUriComponentsBuilder ucb =ServletUriComponentsBuilder.fromContextPath(request)
       .path("/accounts").build()

        或者,在DispatcherServlet已基于名字进行了映射时(比如/main/*这种),你也可以获得servlet映射所包含的部分值,如下:

// 重用 host, port,context path
// 追加servlet映射到路径下的部分值
// 追加"/accounts" 到路径上
 
ServletUriComponentsBuilder ucb =ServletUriComponentsBuilder.fromServletMapping(request)
       .path("/accounts").build()

21.7.1 组建连接到controller和方法的URI

       Spring MVC提供了一种机制,能组建连接到controller的方法中的链接,如下例所示:

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

       在上面的例子中,我们提供了实际的方法入参值,在此情况下,这个长整形值21会被看作路径变量来使用,并且把它添加到URL中。此外,我们提供了42这个值,用来填补在URI中剩余的变量,比如从类级别请求映射中继承的”hotel”变量。如果在这个方法里有更多的入参,你能够为那些URL并不需要的入参设置为null。一般来说,只有@PathVariable和@RequestParam的入参与构建URL相关。

       还有一种额外的方法来使用MvcUriComponentsBuilder。例如:你可以使用某种类似mock测试的技术,这种技术通过代理来避免基于名称来参考匹配控制器的方法。(下面的例子假设静态导入了MvcUriComponentsBuilder.on):

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

       上面的例子使用MvcUriComponentsBuilder中的静态方法。在这个方法内部,它们依赖于ServletUriComponentsBuilder来从现存的请求中,根据它的scheme(结构), host, port(端口),context路径和servlet路径,准备好URL。再多数情况下,这样效果很好,但有些情况下,可能会效率低下。例如:你可能会在请求的context的外面(比如:链接准备时的批量处理过程)或者你需要插入一个路径的前缀(例如: 本地前缀从请求路径中被移除了,并且需要重新添加到链接中)。

       在这种情况下,你可以使用静态的”fromXxx”重载的方法来允许一个UriComponentsBuilder来使用URL。或者,你可以创建一个带有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();

21.7.2 在视图中组建连接到controller和方法中的URI

       你同样可以从类似JSP,Thymeleaf, FreeMarker等视图中,组建链接到注解式controller中。可以通过使用MvcUriComponentsBuilder中的fromMappingName方法来实现,这个方法是基于名字来进行映射的。

       每一个@RequestMapping都被赋予了一个默认名,这个名字默认是类名中的大写字母加上方法名的全称。例如,有个方法叫”getFoo”,这个方法在FooController中,那么这个默认名就是”FC#getFoo”。这种命名的策略还可以通过创建HandlerMethodMappingNamingStrategy的实例,并把这个实例加入进你的RequestMappingHandlerMapping中来进行自定义。这种默认策略的实现,也会在@RequestMapping中的name属性存在时进行使用。这表示,默认指定的映射名与另一个名字冲突的时候(比如:重载的方法),你可以在@RequestMapping上显式地为其指定一个名字。

 

请注意:

       这些被指定了的请求映射名会在启动时的TRACE级别记录日志。

 

       Spring的JSP标签库提供了一个叫做mvcUrl的功能,这个功能能基于它的的机制,来把需要连接到controller方法的链接准备到位。如下例:

@RequestMapping("/people/{id}/addresses")
public class PersonAddressController {
 
    @RequestMapping("/{country}")
    public HttpEntity 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>

       上面的例子中,依赖了在JSP中声明了Spring标签库(比如META-INF/spring.tld)的 mvcUrl这个功能。若需处理更多进阶的情况(比如在上一节讲到过的自定义URL),为了使用拥有一个自定基础URL的特定的MvcUriComponentsBuilder实例,来自定义一个功能,或者是使用自定义的标签文件,都是很方便的。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Web MVC 框架中,URI Builder 是一个用于构建 URI 的工具类。它可以让你在构建 URI 时更加方便和灵活。 下面我们通过一个例子来演示如何使用 URI Builder。 假设我们有一个控制器方法,它的访问路径为 `/users/{id}`,其中 `{id}` 是一个路径变量,表示用户 ID。我们想要构建这个路径的 URI,同时还想为这个 URI 添加一些查询参数,比如 `name` 和 `age`。我们可以使用 URI Builder 来完成这个任务,代码如下: ```java import org.springframework.web.util.UriComponentsBuilder; ... @RequestMapping("/users/{id}") public String getUser(@PathVariable int id, @RequestParam String name, @RequestParam int age) { UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/users/{id}") .queryParam("name", name) .queryParam("age", age); String uri = builder.buildAndExpand(id).toUriString(); // ... return "user"; } ``` 在上面的代码中,我们首先使用 `UriComponentsBuilder.fromPath()` 方法创建一个 URI Builder 对象,并指定路径为 `/users/{id}`,这里的 `{id}` 是一个路径变量。接着,我们使用 `queryParam()` 方法添加查询参数。最后,我们调用 `buildAndExpand()` 方法来替换路径变量,并构建最终的 URI。 需要注意的是,在使用 `buildAndExpand()` 方法时,我们将用户 ID 作为参数传递给了这个方法。这是因为我们在 URI 中使用了路径变量 `{id}`,需要将其替换为实际的值。 最终,我们调用 `toUriString()` 方法将 URI Builder 对象转换为字符串形式,返回给浏览器。 除了上面的例子,URI Builder 还提供了很多其他的方法,可以让你更加灵活地构建 URI。如果你想要了解更多信息,可以查看 Spring 官方文档中关于 URI Builder 的介绍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值