简体   繁体   English

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

[英]How to create URI/URL using MultiValueMap for parameters?

I have multimap of parameters, like this:我有参数的多图,如下所示:

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

as spring MultiValueMap and I'm trying to create URI from this, I tried to use作为 spring MultiValueMap并且我正在尝试从中创建 URI,我尝试使用

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

It seems to work for special chars, but it still does think that + sign is a space, I want to encode all parameters, is there existing solution for this other than manually encoding each value?它似乎适用于特殊字符,但它仍然认为+符号是一个空格,我想对所有参数进行编码,除了手动编码每个值之外,是否还有现有的解决方案?

Assuming you are on Spring 5.0, this is discussed in detail in [SPR-16860] Spring is inconsistent in the encoding/decoding of URLs issue.假设您使用的是 Spring 5.0,这在[SPR-16860]中详细讨论了Spring 在 URL 的编码/解码问题中不一致 More or less it boils down to this:或多或少归结为:

From an RFC 3986 perspecitve, "+" is a legal character.从 RFC 3986 的角度来看,“+”是一个合法字符。 By default the RestTemplate leaves it as is.默认情况下, RestTemplate 保持原样。

UriComponents.encode() will leave + sign as is, to stay complaint with the RFC 3986. If you need it encoded one suggestion is to use UriUtils : UriComponents.encode()将保持+符号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();

There is a change coming 5.0.8 as part of [SPR-17039] Support stricter encoding of URI variables in UriComponents which introduces new UriComponentsBuilder.encode() method.作为[SPR-17039] 的一部分,在 5.0.8 中有一个变化,支持对 UriComponents 中的 URI 变量进行更严格的编码,它引入了新的UriComponentsBuilder.encode()方法。 It should be enough to move encode() before build() in your example:在您的示例中,在build()之前移动encode()应该就足够了:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM