【问题标题】:Correct URL encoding of # Java WebClient#Java WebClient 的正确 URL 编码
【发布时间】:2021-04-14 14:52:44
【问题描述】:

我正在尝试使用此代码从我的 API 中检索数据:

        Mono<String> client = WebClient.builder()
          .baseUrl("https://localhost:8081/getPost/" + id) // or URLEncoder.encode(id, "UTF-8")
          .defaultHeaders(new Consumer<HttpHeaders>() {
              @Override
              public void accept(HttpHeaders httpHeaders) {
                httpHeaders.addAll(createHeaders());
              }
            })
          .build()
          .get()
          .retrieve()
          .bodyToMono(String.class);

我的 ID 以“#”开头,所以如果我使用此代码,它将导致:

https://localhost:8081/getPost/#id1

问题是我需要对它进行 url 编码,所以它应该是 getPost/%23id1,我尝试在 id 上使用 URLEncoder 但结果是双重编码:

 https://localhost:8081/getPost/%25%23id1

我需要摆脱那个 %25

【问题讨论】:

  • 很抱歉,但我认为你不能.. %23 是因为 # 是 reserved character(一些参考 herehere)。希望对你有帮助
  • 我知道 # 是保留的,但是如果我使用上面的代码,则 url 将导致 /#id 而我需要 /%23id。我在 php 上使用相同的 API,并使用 %23 对 # 进行编码。我不知道为什么Java允许#char不编码
  • 对不起,我没有直截了当,但你说得很清楚。这种行为很奇怪。我试图重现您的代码here,它似乎有效。 %25代表%,你的id字符串里有类似的吗?

标签: java spring-webclient


【解决方案1】:

WebClient.builder().baseUrl 未能正确编码保留字符“#”似乎很奇怪。如果你看一下文档,它说它相当于.uriBuilderFactory(new DefaultUriBuilderFactory(baseUrl))。因此,您可以进行自己的 URL 编码,但在 WebClient 中将其抑制:

DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(
        "https://localhost:8081/getPost/" + URLEncoder.encode(id, "UTF-8"));
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT);
Mono<String> client = WebClient.builder()
          .uriBuilderFactory(factory)
          .defaultHeaders(...)
          .build()
          ...etc...

【讨论】: