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的功能?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM