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:
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 for UriComponents
which
Represents an immutable collection of URI components, mapping component type to
String
values.
The URI specification defines what characters are allowed in a URI. This answer summarizes the list to the characters
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
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.
The method URLEncoder#encode(String, String)
Translates a string into
application/x-www-form-urlencoded
format using a specific encoding scheme.
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 input url
into
http%3A%2F%2Fquery.param%2Fexample
The character %
is invalid in a URI so must be encoded. That's what the UriComponents
object constructed by your UriComponentsBuilder
is doing.
This is unnecessary since your URI is completely valid to begin with. Get rid of the use of URLEncoder
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With