Affects: \6.1.3
If RestClient Builder is created from a RestTemplate an attempt to set a the baseUrl
would leads to the java.lang.IllegalArgumentException: URI is not absolute
exception.
To reproduce:
@Test
public void test2() {
String baseUrl = "https://dog.ceo";
RestTemplate restTemplate = new RestTemplate();
var restClient = RestClient.builder(restTemplate).baseUrl(baseUrl).build();
String res = restClient.get().uri("/api/breeds/list/all").retrieve().body(String.class);
assertThat(res).isNotNull();
}
would throw:
java.lang.IllegalArgumentException: URI is not absolute
at java.base/java.net.URL.fromURI([URL.java:721](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html))
at java.base/java.net.URI.toURL([URI.java:1139](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html))
at org.springframework.http.client.SimpleClientHttpRequestFactory.createRequest([SimpleClientHttpRequestFactory.java:154](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html))
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.createRequest([DefaultRestClient.java:528](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html))
Note: If you set the restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(baseUrl));
before creating the builder it won't fail.
Comment From: Akaame
@poutsma I reproduced this and what happens is clear:
private UriBuilderFactory initUriBuilderFactory() {
if (this.uriBuilderFactory != null) {
return this.uriBuilderFactory;
}
DefaultUriBuilderFactory factory = (this.baseUrl != null ?
new DefaultUriBuilderFactory(this.baseUrl) : new DefaultUriBuilderFactory());
factory.setDefaultUriVariables(this.defaultUriVariables);
return factory;
}
The condition here is not respected because of the DefaultUriBuilderFactory. This is what I am seeing:
Therefore the baseUrl
is never respected. The code works when the setUriTemplateHandler
is called with a UriBuilderFactory
explicitly because it creates instances with baseUrl
already. I have not contributed Spring enough to suggest the best solution here. Maybe it is advisable to ensure either the existence of this.uriBuilderFactory.baseUrl
or the this.baseUrl
itself.
Comment From: jhoeller
@poutsma I'm replacing hasRestTemplateDefaults()
with hasBaseUri()
in DefaultUriBuilderFactory
since this allows for keeping the actual RestTemplate-style settings check in DefaultRestClientBuilder
itself where it conceptually fits better.
Not least of it all, RestClient
and RestTemplate
live in the web.client
package whereas DefaultUriBuilderFactory
lives in web.util
where it shouldn't logically depend on RestTemplate
and its default settings, in particular not in a public method name.