使用Spring的RestTemplate避免URL查询参数的双重编码 [英] Avoid Double Encoding of URL query param with Spring's RestTemplate
问题描述
我正在尝试使用Spring的RestTemplate :: getForObject来请求具有URL查询参数的URL。
I'm trying to use Spring's RestTemplate::getForObject to make a request for a URL which has a URL query param.
我已经尝试过:
- 使用字符串
- 使用URI :: new
- 使用URI :: create
- 使用UriComponentsBuilder构建URI
创建URI
创建URI
- Using a string
- Creating a URI with URI::new
- Creating a URI with URI::create
- Using UriComponentsBuilder to build the URI
无论使用哪种方法,使用URLEncoder :: encode编码url查询参数都会进行双重编码,并且使用这种编码方式会使url查询参数保持未编码状态。
No matter which of these I use, encoding the url query param with URLEncoder::encode gets double encoded and using this encoding leaves the url query param unencoded.
如何在不对URL进行双重编码的情况下发送此请求?方法如下:
How can I send this request without double encoding the URL? Here's the method:
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:
Without URLEncoder:
http://www.example.com/query?url=http://query.param/example&api_key=KEY&api_secret=SECRET
使用URLEncoder:
With URLEncoder:
http://www.example.com/query?url=http%253A%252F%252Fquery.param%252Fexample&api_key=KEY&api_secret=SECRET
':'应该被编码为%3A,'/'应该被编码为%2F。确实发生了-但随后%被编码为%25。
':' should be encoded as %3A and '/' should be encoded as %2F. This does happen - but then the % is encoded as %25.
推荐答案
A UriComponentsBuilder
是 UriComponents
的构建器,其中
A UriComponentsBuilder
is a builder for UriComponents
which
表示一个不可变的集合。 URI组件,将组件类型映射到
String
值。
URI规范定义URI中允许使用哪些字符。 此答案将字符列表汇总为
The URI specification defines what characters are allowed in a URI. This answer summarizes the list to the characters
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 -._〜:/?#[] @!$&'()* +,; =
通过这些规则,您的URI
By those rules, your URI
http://www.example.com/query?url=http://query.param/example&api_key=KEY&api_secret=SECRET
完全有效,不需要其他编码。
is perfectly valid and requires no additional encoding.
方法 URLEncoder#encode(String,String)
将字符串转换为
application / x-www-form-urlencoded
格式使用特定的编码方案。
Translates a string into
application/x-www-form-urlencoded
format using a specific encoding scheme.
那是不一样的。在此处和 URLEncoder
(afaik)应该密切关注它。
That is not the same thing. That process is defined here, and URLEncoder
(afaik) should be following it pretty closely.
在您的原始代码中,使用 URLEncoder#encode
转换了您的输入 url
进入
In your original code, using URLEncoder#encode
converted your input url
into
http%3A%2F%2Fquery.param%2Fexample
字符%
在URI中无效,因此必须进行编码。这就是 UriComponentsBuilder
构造的 UriComponents
对象的作用。
The character %
is invalid in a URI so must be encoded. That's what the UriComponents
object constructed by your UriComponentsBuilder
is doing.
这是不必要的,因为您的URI完全是有效的。摆脱使用 URLEncoder
。
This is unnecessary since your URI is completely valid to begin with. Get rid of the use of URLEncoder
.
这篇关于使用Spring的RestTemplate避免URL查询参数的双重编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!