1. 簡介
本教程將重點介紹 Spring 的 <em UriComponentsBuilder</em>>。 尤其是,我們將描述各種實際的實現示例。
UriComponentsBuilder 與 <em UriComponents</em>> 類協同工作,<em UriComponents</em>> 是一個不可變的 URI 組件容器。
一個新的 <em UriComponentsBuilder</em>> 類有助於通過對準備 URI 的各個方面(包括構建、從模板變量擴展和編碼)提供精細控制來創建 <em UriComponents</em>> 實例。
2. Maven 依賴
為了使用構建器,我們需要在我們的 <em>pom.xml</em> 的 <em>dependencies</em> 部分中包含以下內容:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
最新版本可以在這裏找到:這裏。
這個依賴僅涵蓋 Spring Web,請務必添加 spring-context 以構建完整的 Web 應用程序。
我們當然還需要為項目設置日誌記錄——關於此處的更多信息。
3. 應用場景
UriComponentsBuilder 具有許多實際應用場景,從對 URI 組件中未被允許的字符的上下文編碼,到動態替換 URL 的部分,應有盡有。
UriComponentsBuilder 的最大優勢在於 我們可以將其直接注入到控制器方法中:
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity createCustomer(UriComponentsBuilder builder) {
// implementation
}讓我們逐步描述一些有用的示例。我們將立即使用 JUnit 框架測試我們的實現。
3.1. 構建 URI
讓我們從最簡單的開始。我們想要使用 <em >UriComponentsBuilder</em> 來創建簡單的鏈接:
@Test
public void constructUri() {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.scheme("http").host("www.baeldung.com").path("/junit-5").build();
assertEquals("/junit-5", uriComponents.toUriString());
}如我們所見,我們創建了一個新的 UriComponentsBuilder 實例,然後提供了 scheme 類型、主機名和請求目標路徑。
這個簡單的示例可能在我們需要將網站的其他部分/鏈接重定向時非常有用。
3.2. 構建編碼後的 URI
除了創建簡單的鏈接之外,我們可能需要對最終結果進行編碼。下面我們來看一個實際例子:
@Test
public void constructUriEncoded() {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.scheme("http").host("www.baeldung.com").path("/junit 5").build().encode();
assertEquals("/junit%205", uriComponents.toUriString());
}本示例的差異在於我們希望在單詞 junit 和數字 5 之間添加空格。根據 RFC 3986,這是不允許的。我們需要使用 encode() 方法來編碼鏈接,才能獲得有效結果。
3.3. 從模板構建 URI
URI 模板允許在 URI 的大多數組件中使用,但其值僅限於特定元素,我們將其標記為模板。下面來看一個示例以更清楚地説明:
@Test
public void constructUriFromTemplate() {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.scheme("http").host("www.baeldung.com").path("/{article-name}")
.buildAndExpand("junit-5");
assertEquals("/junit-5", uriComponents.toUriString());
}在本示例中,差異在於我們聲明路徑的方式以及如何構建最終 URI。將被關鍵詞替換的模板用方括號指示——<em>{…}</em>位於<em>path()</em>方法內部。用於生成最終鏈接的關鍵詞在名為<em>buildAndExpand(…)</em>的方法中使用。
請注意,可能存在多個關鍵詞需要替換。此外,URI 的路徑可以是相對路徑。
此示例在我們需要根據 Spring 控制器將模型對象傳遞時將非常有用。
3.4. 使用查詢參數構建 URI
另一個非常有用的場景是使用查詢參數構建 URI。
我們需要使用 <em>query()</em> 方法來自 <em>UriComponentsBuilder</em> 中指定 URI 查詢參數。 讓我們看下面的示例:
@Test
public void constructUriWithQueryParameter() {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.scheme("http").host("www.google.com")
.path("/").query("q={keyword}").buildAndExpand("baeldung");
assertEquals("http://www.google.com/?q=baeldung", uriComponents.toUriString());
}查詢將添加到鏈接的主體部分。我們可以使用括號 {…} 傳遞多個查詢參數。它們將被替換為 buildAndExpand(…) 方法中的關鍵字。
此 UriComponentsBuilder 的實現可能被用於構建,例如,用於 REST API 的查詢語言。
3.5. 使用正則表達式擴展 URI
以下示例展示了使用正則表達式構建 URI 並進行驗證的過程。只有在正則表達式驗證成功的情況下,我們才能擴展 uriComponents:
@Test
public void expandWithRegexVar() {
String template = "/myurl/{name:[a-z]{1,5}}/show";
UriComponents uriComponents = UriComponentsBuilder.fromUriString(template)
.build();
uriComponents = uriComponents.expand(Collections.singletonMap("name", "test"));
assertEquals("/myurl/test/show", uriComponents.getPath());
}在上述示例中,我們可以看到鏈接的中間部分只能包含 a-z 範圍內的字母,且長度在 1-5 之間。
我們還使用 singletonMap,將關鍵詞 name 替換為值 test。
此示例在啓用用户動態指定鏈接時尤其有用,但同時我們希望提供一種安全機制,確保僅允許有效的鏈接在我們的 Web 應用程序中工作。
4. 結論
本教程介紹了 UriComponentsBuilder 的實用示例。
UriComponentsBuilder 的主要優勢在於使用 URI 模板變量的靈活性,以及直接將其注入到 Spring Controller 方法中的可能性。