概述
本教程将重点介绍Spring的UriComponentsBuilder
。我们将描述各种实际的实现示例。
UriComponentsBuilder
与UriComponents
类协同工作,后者是URI组件的不可变容器。
通过UriComponentsBuilder
类,我们可以细致地控制URI的各个方面,包括构建、模板变量的展开以及编码。
Maven依赖
为了使用这个构建器,我们需要在pom.xml
的dependencies
部分添加以下内容:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
最新的版本可以在这里找到。
这个依赖仅涵盖了Spring Web,因此对于完整的Web应用,别忘了添加spring-context
。
当然,我们还需要为项目设置日志记录——更多内容请参考这里。
用例
UriComponentsBuilder
有许多实用场景,从对相应URI组件中不允许的字符进行上下文编码,到动态替换URL的某些部分。
UriComponentsBuilder
的一个主要优势是我们可以直接将其注入控制器方法:
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity createCustomer(UriComponentsBuilder builder) {
// implementation
}
现在让我们逐一描述有用的示例,并立即使用JUnit框架进行测试。
3.1. 构建URI
我们从最简单的开始。我们想要使用UriComponentsBuilder
创建一个简单的链接:
@Test
public void constructUri() {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.scheme("http").host("www.baeldung.com").path("/junit-5").build();
assertEquals("/junit-5", uriComponents.toUriString());
}
我们可以看到,我们创建了一个新的UriComponentsBuilder
实例,然后提供了协议类型、主机和请求目的地的路径。
当需要重定向到网站的其他部分或链接时,这个简单的示例可能很有用。
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。模板将在path()
方法中用关键字替换的部分由方括号{…}
表示。用于生成最终链接的关键字在名为buildAndExpand(…)
的方法中使用。
请注意,可能有多个关键字需要替换。URI的路径可以是相对的。
当想要基于传递给Spring控制器的模型对象构建URI时,这个示例非常有用。
3.4. 使用查询参数构建URI
另一个非常有用的情况是创建带有查询参数的URI。
我们需要使用UriComponentsBuilder
的query()
方法指定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());
}
在上述示例中,我们可以看到链接的中间部分只能包含小写字母,长度在1-5范围内。
此外,我们使用了singletonMap
,将关键词name
替换为test
。
当允许用户动态指定链接,但又想为我们的Web应用提供某种安全措施(只允许有效的链接工作)时,这个示例特别有用。
总结
本教程展示了UriComponentsBuilder
的实用示例。
UriComponentsBuilder
的主要优点是使用URI模板变量的灵活性,以及直接注入Spring控制器方法的可能性。
所有示例和配置可在GitHub上找到。