在 JAX-RS 中转义查询参数中的“%”符号

Escaping `%` symbol in query parameter in JAX-RS

我尝试使用 Jersey 或 Resteasy

发送带有一些 URL 字符串作为参数的 GET 请求
Response response = new ResteasyClientBuilder()
        .build()
        .target(UriBuilder.fromPath("https://foo.bar"))
        .queryParam("url", "http://hostname.com/The%20URL%20with spaces.jpg")
        .request()
        .get();

两种实现都发送
https://foo.bar?url=http%3A%2F%2Fhostname.com%2FThe%20URL%20with%20spaces.jpg

我假设原来的 space 是用 %20 转义的,而原来的 %20 在查询参数中是双重转义的。
但事实并非如此。
原始 space 和 %20 混合在一起,在服务器端我得到未转义的字符串,所有 %20 都转换为 spaces 并且字符串被破坏。

根据 source code of Resteasy,它 "Keeps encoded values "%...“和模板参数完好无损”。但是我没有在 JEE 文档中找到关于此行为的任何文字。

我应该在将字符串添加为参数之前对其进行转义吗?
我应该使用什么转义器来确保它转义了所有 "%..." and template parameters,并且它在参数中转义的所有内容都被服务器成功地转义了?

标准 JAX-RS WebTarget 的解决方案是不直接应用参数,而是将它们作为模板参数应用。

Response response = new ResteasyClientBuilder()
        .build()
        .target(UriBuilder.fromPath("https://foo.bar"))
        .queryParam("url", "{urlTemplate}")
        .resolveTemplate("urlTemplate", "http://hostname.com/The%20URL%20with spaces.jpg")
        .request()
        .get();

首先,我们添加一些模板{urlTemplate}作为参数值,然后用真实值渲染这个模板。
WebTarget 总是假设给定的参数是一个可能的模板,并且不转义某些字符
但是 .resolveTemplate() 保证转义所有应该转义的字符