[英]How to encode properly the plus sign (+) when making a request with webflux webclient?
I am trying to send an international formatted phone number using spring Webflux Webclient and to read this phone number via another application also using webflux.我正在尝试使用 spring Webflux Webclient 发送国际格式的电话号码,并通过另一个也使用 webflux 的应用程序读取此电话号码。
My code looks like this:我的代码如下所示:
webClient = WebClient.builder()
.baseUrl(baseUrl)
.build();
return webClient
.get()
.uri(uriBuilder -> uriBuilder
.path("/endpoint")
.queryParam("phone-number", "+33612345678")
.build()
)
.retrieve()
.bodyToMono(String.class);
Unfortunately, somewhere between this call and the receiver, the plus sign is replaced by a space.不幸的是,在这个调用和接收者之间的某个地方,加号被一个空格代替了。 The endpoint receives: " 33612345678" as a String.
端点接收:“33612345678”作为字符串。
The.netty debug log of the request shows this:请求的 .netty 调试日志显示如下:
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 63 75 73 74 6f 6d 65 72 73 3f 70 |GET /endpoint?p|
|00000010| 68 6f 6e 65 2d 6e 75 6d 62 65 72 3d 2b 33 33 36 |hone-number=+336|
|00000020| 31 32 33 34 35 36 37 38 26 6f 6e 6c 79 2d 72 65 |12345678
I tried to encode the phone-number by myself like this:我试图像这样自己编码电话号码:
.queryParam("phone-number", UriUtils.encode("+34612345678", StandardCharsets.UTF_8))
And.netty's log shows: and.netty的日志显示:
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 63 75 73 74 6f 6d 65 72 73 3f 70 |GET /endpoint?p|
|00000010| 68 6f 6e 65 2d 6e 75 6d 62 65 72 3d 25 32 35 32 |hone-number=%252|
|00000020| 42 33 34 36 31 32 33 34 35 36 37 38 20 48 54 54 |B34612345678 HTT|
It seems that the phone number has been encoded twice.电话号码似乎被编码了两次。
+ -> %2B -> %252B + -> %2B -> %252B
the plus sign has been encoded by UriUtils.encode
then uriBuilder has encoded the %.加号已由
UriUtils.encode
编码,然后 uriBuilder 已编码 %。
The only way I found to make it work is by disabling the encoding of the UriBuilder:我发现让它工作的唯一方法是禁用 UriBuilder 的编码:
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
this.webClient = WebClient.builder()
.baseUrl(baseUrl)
.uriBuilderFactory(factory)
.build();
and having my custom encoding UriUtils.encode("+34612345678", StandardCharsets.UTF_8)
并使用我的自定义编码
UriUtils.encode("+34612345678", StandardCharsets.UTF_8)
in which case the.netty's logs looks like expected:在这种情况下 the.netty 的日志看起来像预期的那样:
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 63 75 73 74 6f 6d 65 72 73 3f 70 |GET /endpoint?p|
|00000010| 68 6f 6e 65 2d 6e 75 6d 62 65 72 3d 25 32 42 33 |hone-number=%2B3|
|00000020| 34 36 31 32 33 34 35 36 37 38 20 48 54 54 50 2f |4612345678 HTTP/|
And of course, the endpoint receiving the phone number get: "+33612345678"当然,接收电话号码的端点得到:“+33612345678”
To sum it up, it looks like the UriBuilder is encoding certain sign like "%" but does not encode the "+" sign.总而言之,UriBuilder 似乎正在对某些符号(如“%”)进行编码,但并未对“+”符号进行编码。 Spring reference: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#web-uri-encoding
Spring参考: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#web-uri-encoding
I am trying to send an international formatted phone number using spring Webflux Webclient and to read this phone number via another application also using webflux.我正在尝试使用 spring Webflux Webclient 发送一个国际格式的电话号码,并通过另一个也使用 webflux 的应用程序读取此电话号码。
My code looks like this :我的代码如下所示:
webClient = WebClient.builder()
.baseUrl(baseUrl)
.build();
return webClient
.get()
.uri(uriBuilder -> uriBuilder
.path("/endpoint")
.queryParam("phone-number", "+33612345678")
.build()
)
.retrieve()
.bodyToMono(String.class);
Unfortunately, somewhere between this call and the receiver, the plus sign is replaced by a space.不幸的是,在这个调用和接收器之间的某个地方,加号被一个空格代替。 The endpoint receives : " 33612345678" as a String.
端点接收:“33612345678”作为字符串。
The netty debug log of the request shows this :请求的 netty 调试日志显示:
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 63 75 73 74 6f 6d 65 72 73 3f 70 |GET /endpoint?p|
|00000010| 68 6f 6e 65 2d 6e 75 6d 62 65 72 3d 2b 33 33 36 |hone-number=+336|
|00000020| 31 32 33 34 35 36 37 38 26 6f 6e 6c 79 2d 72 65 |12345678
I tried to encode the phone-number by myself like this :我试着像这样自己编码电话号码:
.queryParam("phone-number", UriUtils.encode("+34612345678", StandardCharsets.UTF_8))
And netty's log shows : netty 的日志显示:
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 63 75 73 74 6f 6d 65 72 73 3f 70 |GET /endpoint?p|
|00000010| 68 6f 6e 65 2d 6e 75 6d 62 65 72 3d 25 32 35 32 |hone-number=%252|
|00000020| 42 33 34 36 31 32 33 34 35 36 37 38 20 48 54 54 |B34612345678 HTT|
It seems that the phone number has been encoded twice.电话号码似乎被编码了两次。
+ -> %2B -> %252B + -> %2B -> %252B
the plus sign has been encoded by UriUtils.encode
then uriBuilder has encoded the %.加号已由
UriUtils.encode
编码,然后 uriBuilder 已对 % 进行编码。
The only way I found to make it work is by disabling the encoding of the UriBuilder :我发现让它工作的唯一方法是禁用 UriBuilder 的编码:
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
this.webClient = WebClient.builder()
.baseUrl(baseUrl)
.uriBuilderFactory(factory)
.build();
and having my custom encoding UriUtils.encode("+34612345678", StandardCharsets.UTF_8)
并拥有我的自定义编码
UriUtils.encode("+34612345678", StandardCharsets.UTF_8)
in which case the netty's logs looks like expected :在这种情况下,netty 的日志看起来像预期的那样:
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 63 75 73 74 6f 6d 65 72 73 3f 70 |GET /endpoint?p|
|00000010| 68 6f 6e 65 2d 6e 75 6d 62 65 72 3d 25 32 42 33 |hone-number=%2B3|
|00000020| 34 36 31 32 33 34 35 36 37 38 20 48 54 54 50 2f |4612345678 HTTP/|
And of course, the endpoint receiving the phone number get : "+33612345678"当然,接收电话号码的端点会得到:“+33612345678”
To sum it up, it looks like the UriBuilder is encoding certain sign like "%" but does not encode the "+" sign.总而言之,看起来 UriBuilder 正在编码诸如“%”之类的某些符号,但没有对“+”符号进行编码。 Spring reference : https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#web-uri-encoding
弹簧参考: https : //docs.spring.io/spring-framework/docs/current/reference/html/web.html#web-uri-encoding
I had the same issue and was able to resolve it in my Kotlin application using:我遇到了同样的问题,并且能够在我的 Kotlin 应用程序中使用以下方法解决它:
webClient.get()
.uri { uriBuilder ->
val queryParams = mapOf(
"phone-number" to "+33612345678",
"mobile-number" to "+61432111222"
)
uriBuilder.path("/endpoint")
.apply {
queryParams.keys.forEach { key ->
queryParam(key, "{$key}")
}
}
.build(queryParams)
}
.retrieve()
.bodyToMono<String>()
A solution provided here , you can try this way 这里提供了一个解决方案,你可以试试这个
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
URI uri = factory.uriString("https://spring.io/")
.queryParam("query", "{query}")
.build("spring+framework");
// http://spring.io/?query=spring%2Bframework
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.