我尝试使用Spring的RestTemplate :: getForObject来请求具有URL查询参数的URL。
我试过了:
无论我使用哪一个,使用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。
答案 0 :(得分:10)
UriComponentsBuilder
是UriComponents
的构建者
表示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
。