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?