【问题标题】:Avoid Double Encoding of URL query param with Spring's RestTemplate [duplicate]避免使用 Spring 的 RestTemplate 对 URL 查询参数进行双重编码 [重复]
【发布时间】:2015-12-16 20:21:47
【问题描述】:

我正在尝试使用 Spring 的 RestTemplate::getForObject 来请求具有 URL 查询参数的 URL。

我试过了:

  • 使用字符串
  • 使用 URI::new 创建 URI
  • 使用 URI::create 创建 URI
  • 使用 UriComponentsBuilder 构建 URI

无论我使用哪一个,使用 URLEncoder::encode 对 url 查询参数进行编码都会得到双重编码,而使用这种编码会使 url 查询参数未编码。

如何在不对 URL 进行双重编码的情况下发送此请求?方法如下:

try {
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(detectUrl)
            .queryParam("url", URLEncoder.encode(url, "UTF-8"))
            .queryParam("api_key", "KEY")
            .queryParam("api_secret", "SECRET");
    URI uri = builder.build().toUri();
    JSONObject jsonObject = restTemplate.getForObject(uri, JSONObject.class);
    return jsonObject.getJSONArray("face").length() > 0;
} catch (JSONException | UnsupportedEncodingException e) {
    e.printStackTrace();
}

这是一个例子:

没有 URLEncoder:

http://www.example.com/query?url=http://query.param/example&api_key=KEY&api_secret=SECRET

使用 URLEncoder:

http://www.example.com/query?url=http%253A%252F%252Fquery.param%252Fexample&api_key=KEY&api_secret=SECRET

':' 应编码为 %3A,'/' 应编码为 %2F。这确实发生了 - 但是 % 被编码为 %25。

【问题讨论】:

  • 请提供一个示例 URI 以及它是如何被双重编码的。
  • @SotiriosDelimanolis 我添加了一个 URI 双编码示例。
  • 我不认为 URL 规范要求对 :/ 进行编码。您应该可以直接使用http://www.example.com/query?url=http://query.param/example&api_key=KEY&api_secret=SECRET

标签: java spring encoding


【解决方案1】:

UriComponentsBuilderUriComponents 的构建器

表示不可变的 URI 组件集合,将组件类型映射到 String 值。

URI specification 定义了 URI 中允许使用的字符。 This answer 将列表汇总到字符

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=

根据这些规则,您的 URI

http://www.example.com/query?url=http://query.param/example&api_key=KEY&api_secret=SECRET

完全有效,不需要额外的编码。

方法URLEncoder#encode(String, String)

使用特定的编码方案将字符串转换为application/x-www-form-urlencoded 格式。

那不是一回事。该过程定义为hereURLEncoder (afaik) 应该密切关注它。

在您的原始代码中,使用 URLEncoder#encode 将您的输入 url 转换为

http%3A%2F%2Fquery.param%2Fexample

字符 % 在 URI 中无效,因此必须进行编码。这就是你的UriComponentsBuilder 构造的UriComponents 对象正在做的事情。

这是不必要的,因为您的 URI 一开始就完全有效。摆脱URLEncoder的使用。

【讨论】:

  • 但是如果我在第二个 url 中有一个参数,那么它会产生问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多