Affects: Spring Framework 5.3.13


When creating a RequestEntity with a template and a parameter list, the resulting URL is not available in the created RequestEntity object.

For instance, the following code returns a RequestEntity with a null URL attribute:

RequestEntity<String> r = RequestEntity.post("http://www.example.com/{path}", "myPath").body("");

r.getUrl() throws an UnsupportedOperationException

When looking at the code in RequestEntity.body(String), I see that the returned object is an UriTemplateRequestEntity extending RequestEntity, but this object seems to always have a null URL according to its constructor. Only the uriTemplate, uriVarsArray and uriVarsMap attributes are set. But these attributes are not part of RequestEntity.

So, the URL information is lost in the RequestEntity and to retrieve it, the resulting object must be cast to an UriTemplateRequestEntity, which breaks the encapsulation principle.

Shouldn't the getUrl() method be overridden in UriTemplateRequestEntity?

A similar issue exists here, but it does not seem to fix the root cause.

I also asked a question about that in Stackoverflow but I guess I only will get workarounds.

Comment From: poutsma

There is no guarantee that the variables and template contained in the RequestEntity itself are sufficient to be resolved into a URI. The template might make use of a default URI or default variables, which can only be resolved via a UriBuilderFactory that is typically configured through the RestTemplate. So even if we would override UriTemplateRequestEntity::getUrl, many users would still face exceptions.

Then there is the possibility of users configuring a different encoding mode, which means that the URL returned by UriTemplateRequestEntity::getUrl would not be identical to the one actually resolved by the RestTemplate. Users would be confused by this, and rightfully so.

So instead of implementing UriTemplateRequestEntity::getUrl in a way that still would not work for everyone, and might return invalid results for others, we decided to be clear and not implement the method at all.

Hope that clears things up.

Comment From: mikelhamer

There is no guarantee that the variables and template contained in the RequestEntity itself are sufficient to be resolved into a URI.

So then what should I use if I want to pass around RequestEntity objects and then later retrieve their URL?