Description
When using @HttpExchange clients with a custom RestClient built from a RestTemplate, setting RestTemplateBuilder.rootUri() has no effect on methods that take an URI as a parameter:
``` @Configuration open class Configuration {
@Bean
open fun testClient(): TestClient {
val restTemplateBuilder = RestTemplateBuilder()
.rootUri("https://google.com")
.additionalInterceptors(TestSpringInterceptor())
val restTemplate = restTemplateBuilder.build()
val restClient = RestClient.create(restTemplate)
val clientAdapter = RestClientAdapter.create(restClient)
return HttpServiceProxyFactory
.builderFor(clientAdapter)
.build()
.createClient(TestClient::class.java)
}
}
@HttpExchange interface TestClient {
@GetExchange(url = "/apis")
fun annotationUrl()
@GetExchange
fun parameterUrl(uri: URI)
}
class TestSpringInterceptor : ClientHttpRequestInterceptor { override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse { println("Request URI: ${request.uri}") return execution.execute(request, body) } }
@SpringBootApplication open class App
fun main(args: Array
Setting the base URL through `RestClient.builder().baseUrl()` works but you lose the benefits of customizing the `RestTemplate`. From my debugging, the possible reason for that behaviour is because `DefaultRestClient` has the following code:
public RestClient.RequestBodySpec uri(URI uri) {
if (uri.isAbsolute()) {
this.uri = uri;
} else {
URI baseUri = DefaultRestClient.this.uriBuilderFactory.expand("", new Object[0]);
this.uri = baseUri.resolve(uri);
}
return this;
}
When using `RestTemplateBuilder.rootUri()` the `uriBuilderFactory` here is an instance of `RootUriBuilderFactory`, which in turn fully ignores the base url during expansion:
public URI expand(String uriTemplate, Object... uriVariables) {
return this.handler.expand(this.apply(uriTemplate), uriVariables);
}
String apply(String uriTemplate) {
if (StringUtils.startsWithIgnoreCase(uriTemplate, "/")) { // empty uriTemplate is passed so rootUri does not apply
String var10000 = this.getRootUri();
return var10000 + uriTemplate;
} else {
return uriTemplate;
}
}
``
The different behaviour between passing the URI as a param and setting the URL through the annotation is due toUrlArgumentResolverusingRequestValues.setUri()when URI is passed as an argument andHttpRequestValuesInitializerusingRequestValues.setUriTemplate()when URL is set through@HttpExchange`.