Skip to content

Commit 9e9df0e

Browse files
committed
docs: add docs
1 parent 2510abb commit 9e9df0e

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

boot-uri/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
## 在SpringMVC中优雅的拼接URL
2+
3+
### 背景
4+
5+
> 在日常开发中常常会遇到拼接URL的情况,大多数时候可以手动拼接字符串来达到目的,但是这样的方式不够优雅,同时容易出错。其实SpringMVC中已经给我们提供好了工具,这个工具就是UriComponentsBuilder类。
6+
7+
### 开始
8+
9+
UriComponentsBuilder给我们提供了多种方式来构建不可变的UriComponents实例,要使用这个工具,需要在maven中引入web的依赖:
10+
11+
```
12+
<dependency>
13+
<groupId>org.springframework</groupId>
14+
<artifactId>spring-web</artifactId>
15+
<version>5.1.0.RELEASE</version>
16+
</dependency>
17+
```
18+
这里仅仅引入了web,如果是SpringBoot中,可以直接引入starter。
19+
20+
> 直接通过字符串拼接
21+
22+
```java
23+
String url = "https://api.github.com" + "?" + "token=xxx" + "&name=" + "tomcat";
24+
```
25+
26+
这种方式简单,写起来也不费劲,但问题就是容易出错。
27+
28+
> 通过Guava
29+
30+
Google的Guava中也提供了工具,方便我们拼接URL
31+
32+
```java
33+
// 优雅的拼接出id=1&name=java这样的URL参数
34+
Joiner.on("&").withKeyValueSeparator("=").join(ImmutableMap.of("id", 1, "name", "java"));
35+
// 轻松把URL参数的值转为Map
36+
Splitter.on("&").withKeyValueSeparator("=").split("id=1&name=java");
37+
```
38+
39+
> UriComponentsBuilder
40+
41+
- 构造一个简单的URI
42+
43+
```
44+
@Test
45+
public void constructUri() {
46+
UriComponents uriComponents = UriComponentsBuilder.newInstance()
47+
.scheme("http").host("www.github.com").path("/constructing-uri")
48+
.queryParam("name", "tom")
49+
.build();
50+
51+
assertEquals("/constructing-uri", uriComponents.getPath());
52+
assertEquals("name=tom", uriComponents.getQuery());
53+
assertEquals("/constructing-uri", uriComponents.toUriString());
54+
}
55+
```
56+
57+
`uriComponents`可以使用`toUriString()`方法去输出拼接好的URI地址,这里的结果是:
58+
59+
```
60+
http://www.github.com/constructing-uri?name=tom
61+
```
62+
63+
可以看到`UriComponentsBuilder`是流式API的形式,代码也非常容易理解:
64+
65+
1. scheme:协议,http或者https
66+
2. host:主机地址
67+
3. path:要访问的路径
68+
4. queryParam:url的参数,可以传入多个value
69+
70+
**这个例子在我们后台想重定向到某个地址时非常有用。**
71+
72+
- 构造一个编码的URI
73+
74+
有些参数中携带了特殊符号,这时候需要进行编码,`UriComponentsBuilder`编码也很简单:
75+
76+
```java
77+
@Test
78+
public void constructUriEncoded() {
79+
UriComponents uriComponents = UriComponentsBuilder.newInstance()
80+
.scheme("http").host("www.github.com").path("/constructing uri").build().encode();
81+
82+
assertEquals("/constructing%20uri", uriComponents.getPath());
83+
}
84+
```
85+
86+
- 通过模板构造URI
87+
88+
我们可以通过占位符的方式来构造URI,这种方式是Spring中常常使用的方式,如果用过RestTemplate,那么一定不会陌生。
89+
90+
```java
91+
@Test
92+
public void constructUriFromTemplate() {
93+
UriComponents uriComponents = UriComponentsBuilder.newInstance()
94+
.scheme("http").host("www.github.com").path("/{path-name}")
95+
.query("name={keyword}")
96+
.buildAndExpand("constructing-uri", "tomcat");
97+
98+
assertEquals("/constructing-uri", uriComponents.getPath());
99+
}
100+
```
101+
102+
- 从已有的URI中获取信息
103+
104+
既然存在自己构造URI,那么也有从已知的URI中获取信息的需求,`UriComponentsBuilder`也可以做到
105+
106+
```java
107+
@Test
108+
public void fromUriString() {
109+
UriComponents result = UriComponentsBuilder
110+
.fromUriString("https://www.github.com/constructing-uri?name=tomcat").build();
111+
MultiValueMap<String, String> expectedQueryParams = new LinkedMultiValueMap<>(1);
112+
expectedQueryParams.add("name", "tomcat");
113+
assertEquals(result.getQueryParams(), expectedQueryParams);
114+
}
115+
```
116+
117+
使用`fromUriString()`方法,便可以把一个字符串URI转换为`UriComponents`对象,并且可以通过`getQueryParams()`方法取出参数。
118+
119+
120+
### 总结
121+
122+
`UriComponentsBuilder`的用法远远不止这些,这些例子只是我日常开发中常常用到的,更多的可以参考[docs](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html),代码已经同步到[男性交友网站](https://note.youdao.com/)

0 commit comments

Comments
 (0)