Guide to UriComponentsBuilder in Spring – Spring中的UriComponentsBuilder指南

最后修改: 2016年 11月 25日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

In this tutorial, we are going to focus on the Spring UriComponentsBuilder. More specifically, we’ll describe various practical implementation examples.

在本教程中,我们将重点介绍Spring UriComponentsBuilder。更具体地说,我们将描述各种实际的实现例子。

The builder works in conjunction with the UriComponents class – an immutable container for URI components.

该构建器与UriComponents类一起工作–这是一个不可变的URI组件的容器。

A new UriComponentsBuilder class helps to create UriComponents instances by providing fine-grained control over all aspects of preparing a URI including construction, expansion from template variables, and encoding.

一个新的UriComponentsBuilder类有助于创建UriComponents实例,它提供了对准备URI的所有方面的细粒度控制,包括构造、从模板变量扩展和编码。

2. Maven Dependencies

2.Maven的依赖性

In order to use the builder, we need to include the following section in the dependencies of our pom.xml:

为了使用构建器,我们需要在pom.xmldependencies中包含以下部分。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

The latest version can be found here.

最新版本可以在这里找到。

This dependency only covers Spring Web so don’t forget to add spring-context for a full web application.

这个依赖关系只包括Spring Web,所以别忘了为一个完整的Web应用添加spring-context

We of course also need to set up logging for the project – more on that here.

当然,我们还需要为项目设置日志 – 关于这一点,请看

3. Use Cases

3.使用案例

There are many practical use cases for the UriComponentsBuilder, starting from a contextual encoding of characters not permitted in the corresponding URI component, finishing on replacing parts of the URL dynamically.

UriComponentsBuilder有许多实际的用例,从相应的URI组件中不允许的字符的上下文编码开始,到动态地替换URL的部分内容为止。

One of the biggest advantages of UriComponentsBuilder is that we can inject it right into a controller method:

UriComponentsBuilder的最大优势之一是我们可以将其直接注入控制器方法中

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity createCustomer(UriComponentsBuilder builder) {
    // implementation
}

Let’s start describing useful examples one by one. We’ll use the JUnit framework to test our implementations immediately.

让我们开始逐一描述有用的例子。我们将立即使用JUnit框架来测试我们的实现。

3.1. Constructing a URI

3.1.构建一个URI

Let’s start with the simplest one. We want to use UriComponentsBuilder just to create simple link:

让我们从最简单的一个开始。我们想使用UriComponentsBuilder来创建简单的链接。

@Test
public void constructUri() {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
      .scheme("http").host("www.baeldung.com").path("/junit-5").build();

    assertEquals("/junit-5", uriComponents.toUriString());
}

As we may observe, we created a new instance of UriComponentsBuilder, then we provided scheme type, host, and a path to the request destination.

我们可以看到,我们创建了一个新的UriComponentsBuilder实例,然后我们提供了方案类型、主机和请求目的地的路径。

This simple example might be useful when we want to perform a redirect to other part/link of our website.

当我们想执行重定向到我们网站的其他部分/链接时,这个简单的例子可能很有用。

3.2. Constructing an Encoded URI

3.2.构建一个编码URI

In addition to creating a simple link, we may want to encode the final result. Let’s see this in practice:

除了创建一个简单的链接外,我们可能还想对最终结果进行编码。让我们在实践中看看这个。

@Test
public void constructUriEncoded() {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
      .scheme("http").host("www.baeldung.com").path("/junit 5").build().encode();

    assertEquals("/junit%205", uriComponents.toUriString());
}

The difference in this example is that we want to add space between the word junit and number 5. Accordingly to the RFC 3986, it would not be possible. We need to encode the link to achieve the valid result, using encode() method.

这个例子的不同之处在于,我们想在单词junit和数字5之间添加空格。根据RFC 3986的规定,这是不可能的。我们需要对链接进行编码以达到有效的结果,使用encode()方法。

3.3. Constructing a URI from a Template

3.3.从模板中构建URI

URI templates are allowed in the most components of a URI but their value is restricted to a particular element, that we indicate as a template. Let’s see the example to clarify:

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());
}

The difference in this example is in the way we declare the path and how we build the final URI. Template that will be replaced by keywords is indicated by brackets – {…}, inside the path() method. The keyword that is used to generate the final link is used in the method named buildAndExpand(…).

这个例子的不同之处在于我们声明路径的方式以及我们如何建立最终的URI。将被关键词替换的模板用括号表示 – {…}, path()方法中。用于生成最终链接的关键词被用于名为buildAndExpand(…)的方法中。

Please note, that there might be more than one keyword to be replaced. Also, the path to the URI can be relative.

请注意,要替换的关键词可能不止一个。另外,URI的路径可以是相对的。

This example will be very helpful when we would like to pass model objects to the Spring Controller based on which we’ll build a URI.

当我们想将模型对象传递给Spring控制器时,这个例子将非常有帮助,我们将在此基础上建立一个URI.

3.4. Constructing a URI With Query Parameters

3.4.用查询参数构建URI

Another very useful case is to create URI with query parameters.

另一个非常有用的情况是创建带有查询参数的URI。

We need to use query() from UriComponentsBuilder to specify URI query parameters. Let’s see the following example:

我们需要使用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());
}

The query will be added to the main part of the link. We can provide multiple query parameters, using brackets {…}. They will be replaced by keywords in the method named buildAndExpand(…).

该查询将被添加到链接的主要部分。我们可以提供多个查询参数,使用括号{…}。它们将被名为buildAndExpand(…)的方法中的关键字所取代。

This implementation of UriComponentsBuilder might be used to build – for example – a query language for a REST API.

这个UriComponentsBuilder的实现可用于构建–例如–REST API的查询语言。

3.5. Expanding a URI With Regular Expressions

3.5.用正则表达式扩展URI

The last example is showing a construction of a URI with regex validation. We’ll be able to expand the uriComponents only if regex validation will be successful:

最后一个例子显示的是一个具有重词验证功能的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());
}

In the above-mentioned example, we can see that the middle part of the link needs to have only letters from a-z and the length in a range between 1-5.

在上述例子中,我们可以看到,链接的中间部分需要只有a-z的字母,长度在1-5之间。

Also, we’re using singletonMap, to replace keyword name with value test.

另外,我们使用singletonMap,将关键字name替换为值test

This example is particularly useful when we enable a user to specify links dynamically, but we want to provide a sort of security where only valid links work in our web application.

当我们让用户动态指定链接时,这个例子特别有用,但我们想提供一种安全性,即只有有效的链接才能在我们的网络应用中发挥作用。

4. Conclusion

4.结论

This tutorial presents useful examples of the UriComponentsBuilder.

本教程介绍了UriComponentsBuilder的有用例子。

The main advantages of UriComponentsBuilder are the flexibility of using URI template variables, and a possibility of injecting it directly into Spring Controller methods.

UriComponentsBuilder的主要优点是可以灵活使用URI模板变量,并且可以直接注入Spring控制器方法。

All examples and configurations are available here on GitHub.

所有的例子和配置都可以在GitHub上找到。