如何使用MultiValueMap作为参数创建URI / URL?

时间:2018-10-31 13:47:07

标签: java spring url uri

我有多个参数映射,如下所示:

{
    keyA: ["2+4", "4+8"],
    keyB: ["Some words with special chars #ąęć"]
}

在春季MultiValueMap时,我试图从中创建URI,我尝试使用

URI uri = UriComponentsBuilder
           .fromUriString(baseUri).path(somePath)
           .queryParams(params.getQueryParameters())
           .build().encode().toUri();

它似乎适用于特殊字符,但它仍然认为+符号是一个空格,我想对所有参数进行编码,除了手动编码每个值之外,是否还有解决方案?

1 个答案:

答案 0 :(得分:1)

假设您使用的是Spring 5.0,则在[SPR-16860] Spring is inconsistent in the encoding/decoding of URLs问题中将对此进行详细讨论。或多或少可以归结为:

  

从RFC 3986的角度来看,“ +”是合法字符。默认情况下,RestTemplate保持原样。

UriComponents.encode()将按原样保留+的标志,以保持对RFC 3986的投诉。如果需要它进行编码,一个建议是使用UriUtils

String value = "A+B=C";
value = UriUtils.encode(value, StandardCharsets.UTF_8); // A%2BB%3DC
URI uri = UriComponentsBuilder.newInstance()
       .queryParam("test", value)
       .build(true)
       .toUri();

5.0.8作为[SPR-17039] Support stricter encoding of URI variables in UriComponents的一部分进行了更改,引入了新的UriComponentsBuilder.encode()方法。在您的示例中,将encode()移动到build()之前就足够了:

URI uri = UriComponentsBuilder
       .fromUriString(baseUri).path(somePath)
       .queryParams(params.getQueryParameters())
       .encode()
       .build()
       .toUri();