避免使用Spring的RestTemplate

时间:2015-12-16 20:21:47

标签: java spring encoding

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

我试过了:

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

无论我使用哪一个,使用URLEncoder :: encode对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。

1 个答案:

答案 0 :(得分:10)

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格式。

这不是一回事。该流程定义为here,而URLEncoder(afaik)应该非常密切地关注它。

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

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

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

这是不必要的,因为您的URI完全有效。摆脱URLEncoder

的使用