This question already has an answer here:
I'm trying to use Spring's RestTemplate::getForObject to make a request for a URL which has a URL query param.
I've tried:
- Using a string
- Creating a URI with URI::new
- Creating a URI with URI::create
- Using UriComponentsBuilder to build the URI
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.
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();
}
Here's an example:
Without URLEncoder:
http://www.example.com/query?url=http://query.param/example&api_key=KEY&api_secret=SECRET
With URLEncoder:
http://www.example.com/query?url=http%253A%252F%252Fquery.param%252Fexample&api_key=KEY&api_secret=SECRET
':' should be encoded as %3A and '/' should be encoded as %2F. This does happen - but then the % is encoded as %25.
A
UriComponentsBuilder
is a builder forUriComponents
whichThe URI specification defines what characters are allowed in a URI. This answer summarizes the list to the characters
By those rules, your URI
is perfectly valid and requires no additional encoding.
The method
URLEncoder#encode(String, String)
That is not the same thing. That process is defined here, and
URLEncoder
(afaik) should be following it pretty closely.In your original code, using
URLEncoder#encode
converted your inputurl
intoThe character
%
is invalid in a URI so must be encoded. That's what theUriComponents
object constructed by yourUriComponentsBuilder
is doing.This is unnecessary since your URI is completely valid to begin with. Get rid of the use of
URLEncoder
.