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:

```kotlin @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) { val ctx = runApplication(*args) val testClient = ctx.getBean(TestClient::class.java) testClient.annotationUrl() // prints "Request URI: https://google.com/apis" testClient.parameterUrl(URI.create("/apis")) // prints "Request URI: /apis" }


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:
```java
        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 to UrlArgumentResolver using RequestValues.setUri() when URI is passed as an argument and HttpRequestValuesInitializer using RequestValues.setUriTemplate() when URL is set through @HttpExchange.

e: tested on both 3.5.0 and 4.0.0, problem is present in both

Comment From: rstoyanchev

Yes it looks like RootUriBuilderFactory does not set the baseUrl for the empty path. It would also ignore a path without a leading slash. This will need to be addressed on the Boot side, however, where RestTemplateBuilder and RootUriBuilderFactory are.