当前位置: 首页 > 知识库问答 >
问题:

当使用webflux WebClient发出请求时,如何正确地编码加号(+)?

丘畅
2023-03-14

我试图使用spring Webflux Webclient发送一个国际格式化的电话号码,并通过另一个也使用Webflux的应用程序读取这个电话号码。

我的代码如下所示:

webClient = WebClient.builder()
            .baseUrl(baseUrl)
            .build();

return webClient
            .get()
            .uri(uriBuilder -> uriBuilder
                    .path("/endpoint")
                    .queryParam("phone-number", "+33612345678")
                    .build()
            )
            .retrieve()
            .bodyToMono(String.class);

不幸的是,在这个呼叫和接收者之间的某个地方,加号被空格代替了。endpoint接收到:“33612345678”作为字符串。

请求的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
.queryParam("phone-number", UriUtils.encode("+34612345678", StandardCharsets.UTF_8))

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|

电话号码似乎被编码了两次。

+->%2b->%252b

 DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
    factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
    this.webClient = WebClient.builder()
            .baseUrl(baseUrl)
            .uriBuilderFactory(factory)
            .build();
+--------+-------------------------------------------------+----------------+
|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/|

总而言之,UriBuilder看起来像是在编码“%”之类的符号,但不编码“+”符号。Spring参考:https://docs.Spring.io/Spring-framework/docs/current/reference/html/web.html#web-uri-encoding

共有1个答案

阴礼骞
2023-03-14

我也遇到了同样的问题,但从你链接的Spring参考中找到了一个解决方案

这应该对您有用:

return webClient
            .get()
            .uri(uriBuilder -> UriComponentsBuilder.fromUri(uriBuilder.build())
                    .path("/endpoint")
                    .queryParam("phone-number", "{phone-number}")
                    .encode()
                    .buildAndExpand("+33612345678")
                    .toUri()
            )
            .retrieve()
            .bodyToMono(String.class);
 类似资料:
  • 问题内容: 我有一个复选框,可以切换某些行为,但是如果有人连续点击100次,我不想向服务器端发送100个请求。 到目前为止,这就是我所准备的(找到以下代码片段): 在我的文档准备功能中: 然后事件本身: 这是因为我将1500毫秒作为去抖动周期,所以如果您在1500毫秒内单击n次,它将仅向服务器发送最新状态。 但是,使用它会有副作用,现在我的其他事件的click事件被搞砸了。我在这里做错什么了吗?有

  • 类似于已经存在的问题ApacheHttpClient生成多部分表单post 想要产生一个超文本传输协议请求,持有一个文件和一个key=val对。 目前代码看起来像: 这只是作为实体应用于HttpPost对象并传递给客户端。 它被发送到运行轻量级ttp服务的linux类型设备(黑盒)。问题是,当我发送此请求时,我看不到来自设备的响应(物理的,并且HttpEntity总是返回默认的200 OK)。 通

  • 问题内容: 我想向API发送POST请求,以将我的数据作为内容类型发送。由于我需要管理请求标头,因此我正在使用该方法来创建请求。对于此POST请求,我将数据查询附加到URL上,并将正文保留为空,如下所示: 当我回应时,我总是得到。我相信问题取决于我的请求,API无法理解我要发布的有效负载。我知道类似的方法,但不确定在这种情况下如何使用它。也许我缺少一些其他的Header,也许有更好的方法使用参数将

  • 我试图找到使用httr包通过R连接Appannie的API的方法(根本没有API连接的经验)。API要求包含来自appannie网站的请求标题引用:注册App Annie帐户并生成API密钥。将此密钥添加到您的请求标头中,如下所示: 授权:持有人“”引用 我写了这样的代码 命令http_status(getdata)显示我"客户端错误:(401)未经授权"有人能帮我吗,我做错了什么?

  • 问题内容: 我读了一些将jsons发布到服务器的示例。 有人说: OkHttp是Java提供的HttpUrlConnection接口的实现。它提供用于编写​​内容的输入流,并且不知道(或不在乎)内容的格式。 现在,我想用名称和密码的参数对URL进行常规发布。 这意味着我需要自己将名称和值对编码为流? 问题答案: 当前接受的答案已过期。现在,如果您想创建一个发布请求并向其中添加参数,则应该使用Mul

  • 我阅读了一些将jsons发布到服务器的示例。 有人说: OkHttp是Java提供的HttpUrlConnection接口的实现。它提供了一个用于写入内容的输入流,而不知道(或关心)该内容是什么格式。 现在我想用name和password参数对URL做一个普通的post。 这意味着我需要自己将名称和值对编码成流?