Edited at

springのUriComponentsBuilderでクエリパラメータをエンコード

More than 1 year has passed since last update.


環境

    <parent>

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>


エンコードの指示

encodeでエンコードを指示する。

URI target = UriComponentsBuilder.newInstance()

.scheme("http")
.host("example.com")
.queryParam("foo", "b&r")
.build()
.encode()
.toUri();
System.out.println(target);// http://example.com?foo=b%26r

エンコード済みのURLでfromUriを使う場合はbuild(boolean encoded)trueを指定する。

URI source = new URI("http://example.com?foo=b%26r");

URI target = UriComponentsBuilder
.fromUri(source)
.build(true)
.toUri();
System.out.println(target);// http://example.com?foo=b%26r


ハマった点

もしencodeを指定しない場合、エンコードは行われない。

URI target = UriComponentsBuilder.newInstance()

.scheme("http")
.host("example.com")
.queryParam("foo", "b&r")
.build()
.toUri();
System.out.println(target); // http://example.com?foo=b&r

もしfromUriでエンコード済みのURLを渡し、かつ、build(boolean encoded)trueを指定しない場合、エンコードが行われる。よって、結果的に二重にエンコードが行われる。

URI source = new URI("http://example.com?foo=b%26r");

URI target = UriComponentsBuilder
.fromUri(source)
.build()
.toUri();
System.out.println(target);// http://example.com?foo=b%2526r


参考

[SPR-14256] Doc: UriComponentsBuilder does not encode query parameters - Spring JIRA