Why does RestTemplate have three overloaded methods for each HTTP operation? Supporting tagline
Looking at Spring’s RestTemplate
class, you might wonder why it has three overloaded methods for each HTTP operation. For instance, consider delete
:
detete(String, Object...)
delete(String, Map<String, ?>)
delete(URI)
You will see these three variants throughout RestTemplate: one method that takes a string as first parameter and an array as last, one having taking a string as first and a map as last , and one taking just a java.net.URI
.
The first variant is probably the most popular, as it allows you to easily expand uri variables as a varargs array:
restTemplate.delete("http://example.com/{path}", "foo");
The second variant allows you to expand the same variable twice:
Map<String, ?> vars = Collections.singletonMap("path", "foo");
restTemplate.delete("http://example.com/{path}/{path}", vars);
But perhaps the most interesting one is the final one, taking a URI:
restTemplate.delete(new URI("http://example.com/foo"));
Why do we need an additional method for specifying a URI? Surely we could have used the first, varargs-based variant for that? Something like the following also works fine:
restTemplate.delete("http://example.com/foo");
The reason behind the URI-based variant has to do with URI encodings. If you have string that represent a URI, there is no way to determine if that URI has already been encoded or not. So you run the risk of double-encodings. For instance, the following request
restTemplate.delete("http://example.com/foo%20bar");
probably aims to perform a DELETE request to http://example.com/foo bar
, but instead would connect to http://example.com/foo%2520bar
. The%
character is considered “dangerous” in a path, so it is encoded into %25
.
We use the URI-based variant to solve the issue of double-encodings. In the Javadoc of URI
, we can read that:
The single-argument constructor requires requires any illegal characters in its argument to be quoted and preserves any escaped octets and other characters that are present.
So by using a URI
instead of a String
as parameter, we can be sure that the URI has already been encoded, and won’t do it twice.