在SpringMVC中优雅的拼接URL

在SpringMVC中优雅的拼接URL

背景

在日常开发中常常会遇到拼接URL的情况,大多数时候可以手动拼接字符串来达到目的,但是这样的方式不够优雅,同时容易出错。其实SpringMVC中已经给我们提供好了工具,这个工具就是UriComponentsBuilder类。

开始

UriComponentsBuilder给我们提供了多种方式来构建不可变的UriComponents实例,要使用这个工具,需要在maven中引入web的依赖:

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

这里仅仅引入了web,如果是SpringBoot中,可以直接引入starter。

直接通过字符串拼接

String url = "https://api.github.com" + "?" + "token=xxx" + "&name=" + "tomcat";

这种方式简单,写起来也不费劲,但问题就是容易出错。

通过Guava

Google的Guava中也提供了工具,方便我们拼接URL

// 优雅的拼接出id=1&name=java这样的URL参数
Joiner.on("&").withKeyValueSeparator("=").join(ImmutableMap.of("id", 1, "name", "java"));
// 轻松把URL参数的值转为Map
Splitter.on("&").withKeyValueSeparator("=").split("id=1&name=java");

UriComponentsBuilder

  • 构造一个简单的URI
@Test
public void constructUri() {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
            .scheme("http").host("www.github.com").path("/constructing-uri")
            .queryParam("name", "tom")
            .build();

    assertEquals("/constructing-uri", uriComponents.getPath());
    assertEquals("name=tom", uriComponents.getQuery());
    assertEquals("/constructing-uri", uriComponents.toUriString());
}

uriComponents可以使用toUriString()方法去输出拼接好的URI地址,这里的结果是:

http://www.github.com/constructing-uri?name=tom

可以看到UriComponentsBuilder是流式API的形式,代码也非常容易理解:

1. scheme:协议,http或者https
2. host:主机地址
3. path:要访问的路径
4. queryParam:url的参数,可以传入多个value

这个例子在我们后台想重定向到某个地址时非常有用。

  • 构造一个编码的URI

有些参数中携带了特殊符号,这时候需要进行编码,UriComponentsBuilder编码也很简单:

@Test
public void constructUriEncoded() &#123;
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
            .scheme("http").host("www.github.com").path("/constructing uri").build().encode();

    assertEquals("/constructing%20uri", uriComponents.getPath());
&#125;
  • 通过模板构造URI

我们可以通过占位符的方式来构造URI,这种方式是Spring中常常使用的方式,如果用过RestTemplate,那么一定不会陌生。

@Test
public void constructUriFromTemplate() &#123;
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
            .scheme("http").host("www.github.com").path("/&#123;path-name&#125;")
            .query("name=&#123;keyword&#125;")
            .buildAndExpand("constructing-uri", "tomcat");

    assertEquals("/constructing-uri", uriComponents.getPath());
&#125;
  • 从已有的URI中获取信息

既然存在自己构造URI,那么也有从已知的URI中获取信息的需求,UriComponentsBuilder也可以做到

@Test
public void fromUriString() &#123;
    UriComponents result = UriComponentsBuilder
            .fromUriString("https://www.github.com/constructing-uri?name=tomcat").build();
    MultiValueMap<String, String> expectedQueryParams = new LinkedMultiValueMap<>(1);
    expectedQueryParams.add("name", "tomcat");
    assertEquals(result.getQueryParams(), expectedQueryParams);
&#125;

使用fromUriString()方法,便可以把一个字符串URI转换为UriComponents对象,并且可以通过getQueryParams()方法取出参数。

总结

UriComponentsBuilder的用法远远不止这些,这些例子只是我日常开发中常常用到的,更多的可以参考docs,代码已经同步到男性交友网站


   转载规则

本文不允许转载。
 上一篇
Spring中事务你用对了吗 Spring中事务你用对了吗
Spring中事务你用对了吗 背景 Spring中为JTA,JPA,Hibernate等事务API提供了一致性的编程模型,但是编程式事务需要编码支持,在实际中很少使用。所以Spring提供了声明式事务,配合SpringBoot,我们可以通
2020-04-09
下一篇 
记一次Mybatis Update遇到的坑 记一次Mybatis Update遇到的坑
记一次Mybatis Update遇到的坑背景 最近遇到一个线上问题,由于接手老项目不久,对代码不熟悉,导致这个坑排查了很久才发现。说他是坑吧,其实也不算坑,只能说是由于前人对这个东西不够了解导致的。 简介问题是这样的,在A表中,每次业务
2020-02-10