I'm using Spring Web 5.3.3 with Boot 2.4.2.

When creating a RequestEntity by passing in a URI template, the concrete type created is a UriTemplateRequestEntity, which through its super chain sets this.url = null. Later, when the RequestEntity is passed to RestTemplate#exchange(RequestEntity, Class), the template calls RequestEntity#getUrl. As UriTemplateRequestEntity does not override getUrl, this throws because this.url == null.

Expected use case:

var req = RequestEntity.get("http://localhost/helloworld").build();
var body = restTemplate.exchange(req, String.class);

It appears that what's happening is that the UriTemplateRequestEntity's templating methods are bypassed in the simple exchange flow. While I'm sure that the expectation was that the style above would be used with URI variables, the fact that it throws an obscure exception is Surprising. Instead, I suggest that UriTemplateRequestEntity's getUrl should be overridden, simply returning the string if it is untemplated and possibly throwing an informative exception if it can't be filled out.

Comment From: rstoyanchev

I can't reproduce the issue and I don't see how it can be bypassed. Both exchange methods that take RequestEntity call resolveUrl which does an instanceof check. Please elaborate or provide a sample.

Comment From: chrylis

I think I see the divergence; the root cause seems to actually be upstream in TestRestTemplate. I'll close and re-file against Boot.