zoukankan      html  css  js  c++  java
  • 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的功能?

  • 相关阅读:
    mybatis映射器${}和#{}的区别
    在list里循环放入map,每次map里的值都不一样,可是放入后再取出来就变成一样的
    tomcat 配置 编码方式后,重新启动 配置还原
    三级联动探索
    Excel导入导出的实现
    Servlet实现文件上传下载
    Java数据类型转换汇总
    mysql8.0.13安装
    cmd中命令能用,vs中不能用解决方案
    yii2获取模块、控制器、方法名
  • 原文地址:https://www.cnblogs.com/larryzeal/p/6131664.html
Copyright © 2011-2022 走看看