Browse Source
When Spring Framework builds a `RestClient` from a `RestTemplate`, it will use any `UriTemplateHandler` that has been set on the `RestTemplate` if the provided `UriTemplateHandler` is also a `UriBuilderFactory`. Prior to this commit, Spring Boot's `RestTemplateBuilder#rootUri` set a `UriTemplateHandler` on the created `RestTemplate`, but it was not a `UriBuilderFactory` so `RestClient` would not consider it. With this commit, `RestTemplateBuilder#rootUri` sets a `UriTemplateHandler` that is also a `UriBuilderFactory` so that any root URI that is set on the `RestTemplateBuilder` will be applied to a `RestClient` also. Fixes gh-39317pull/39630/head
9 changed files with 271 additions and 15 deletions
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.test.autoconfigure.web.client; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder; |
||||
import org.springframework.test.web.client.MockRestServiceServer; |
||||
import org.springframework.web.client.RestClient; |
||||
import org.springframework.web.client.RestClient.Builder; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; |
||||
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; |
||||
|
||||
/** |
||||
* Tests for building a {@link RestClient} from a {@link RestTemplateBuilder}. |
||||
* |
||||
* @author Scott Frederick |
||||
*/ |
||||
class RestClientWithRestTemplateBuilderTests { |
||||
|
||||
@Test |
||||
void buildUsingRestTemplateBuilderRootUri() { |
||||
RestTemplate restTemplate = new RestTemplateBuilder().rootUri("https://resttemplate.example.com").build(); |
||||
RestClient.Builder builder = RestClient.builder(restTemplate); |
||||
RestClient client = buildMockedClient(builder, "https://resttemplate.example.com/test"); |
||||
assertThat(client.get().uri("/test").retrieve().toBodilessEntity().getStatusCode().is2xxSuccessful()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
void buildUsingRestClientBuilderBaseUrl() { |
||||
RestTemplate restTemplate = new RestTemplateBuilder().build(); |
||||
RestClient.Builder builder = RestClient.builder(restTemplate).baseUrl("https://restclient.example.com"); |
||||
RestClient client = buildMockedClient(builder, "https://restclient.example.com/test"); |
||||
assertThat(client.get().uri("/test").retrieve().toBodilessEntity().getStatusCode().is2xxSuccessful()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
void buildRestTemplateBuilderRootUriAndRestClientBuilderBaseUrl() { |
||||
RestTemplate restTemplate = new RestTemplateBuilder().rootUri("https://resttemplate.example.com").build(); |
||||
RestClient.Builder builder = RestClient.builder(restTemplate).baseUrl("https://restclient.example.com"); |
||||
RestClient client = buildMockedClient(builder, "https://resttemplate.example.com/test"); |
||||
assertThat(client.get().uri("/test").retrieve().toBodilessEntity().getStatusCode().is2xxSuccessful()).isTrue(); |
||||
} |
||||
|
||||
private RestClient buildMockedClient(Builder builder, String url) { |
||||
MockRestServiceServer server = MockRestServiceServer.bindTo(builder).build(); |
||||
server.expect(requestTo(url)).andRespond(withSuccess()); |
||||
return builder.build(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.test.autoconfigure.web.client; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.test.web.client.MockRestServiceServer; |
||||
import org.springframework.web.client.RestClient; |
||||
import org.springframework.web.client.RestClient.Builder; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.springframework.web.util.DefaultUriBuilderFactory; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; |
||||
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; |
||||
|
||||
/** |
||||
* Tests for building a {@link RestClient} from a {@link RestTemplate}. |
||||
* |
||||
* @author Scott Frederick |
||||
*/ |
||||
class RestClientWithRestTemplateTests { |
||||
|
||||
@Test |
||||
void buildUsingRestTemplateUriTemplateHandler() { |
||||
RestTemplate restTemplate = new RestTemplate(); |
||||
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("https://resttemplate.example.com"); |
||||
restTemplate.setUriTemplateHandler(uriBuilderFactory); |
||||
Builder builder = RestClient.builder(restTemplate); |
||||
RestClient client = buildMockedClient(builder, "https://resttemplate.example.com/test"); |
||||
assertThat(client.get().uri("/test").retrieve().toBodilessEntity().getStatusCode().is2xxSuccessful()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
void buildUsingRestClientBuilderBaseUrl() { |
||||
RestTemplate restTemplate = new RestTemplate(); |
||||
Builder builder = RestClient.builder(restTemplate).baseUrl("https://restclient.example.com"); |
||||
RestClient client = buildMockedClient(builder, "https://restclient.example.com/test"); |
||||
assertThat(client.get().uri("/test").retrieve().toBodilessEntity().getStatusCode().is2xxSuccessful()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
void buildUsingRestTemplateUriTemplateHandlerAndRestClientBuilderBaseUrl() { |
||||
RestTemplate restTemplate = new RestTemplate(); |
||||
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("https://resttemplate.example.com"); |
||||
restTemplate.setUriTemplateHandler(uriBuilderFactory); |
||||
Builder builder = RestClient.builder(restTemplate).baseUrl("https://restclient.example.com"); |
||||
RestClient client = buildMockedClient(builder, "https://resttemplate.example.com/test"); |
||||
assertThat(client.get().uri("/test").retrieve().toBodilessEntity().getStatusCode().is2xxSuccessful()).isTrue(); |
||||
} |
||||
|
||||
private RestClient buildMockedClient(Builder builder, String url) { |
||||
MockRestServiceServer server = MockRestServiceServer.bindTo(builder).build(); |
||||
server.expect(requestTo(url)).andRespond(withSuccess()); |
||||
return builder.build(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.client; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.springframework.web.util.UriBuilder; |
||||
import org.springframework.web.util.UriBuilderFactory; |
||||
import org.springframework.web.util.UriComponentsBuilder; |
||||
import org.springframework.web.util.UriTemplateHandler; |
||||
|
||||
/** |
||||
* {@link UriBuilderFactory} to set the root for URI that starts with {@code '/'}. |
||||
* |
||||
* @author Scott Frederick |
||||
* @since 3.2.3 |
||||
*/ |
||||
public class RootUriBuilderFactory extends RootUriTemplateHandler implements UriBuilderFactory { |
||||
|
||||
@SuppressWarnings("removal") |
||||
RootUriBuilderFactory(String rootUri) { |
||||
super(rootUri); |
||||
} |
||||
|
||||
@SuppressWarnings("removal") |
||||
RootUriBuilderFactory(String rootUri, UriTemplateHandler delegate) { |
||||
super(rootUri, delegate); |
||||
} |
||||
|
||||
@Override |
||||
public UriBuilder uriString(String uriTemplate) { |
||||
return UriComponentsBuilder.fromUriString(apply(uriTemplate)); |
||||
} |
||||
|
||||
@Override |
||||
public UriBuilder builder() { |
||||
return UriComponentsBuilder.newInstance(); |
||||
} |
||||
|
||||
/** |
||||
* Apply a {@link RootUriBuilderFactory} instance to the given {@link RestTemplate}. |
||||
* @param restTemplate the {@link RestTemplate} to add the builder factory to |
||||
* @param rootUri the root URI |
||||
*/ |
||||
static void applyTo(RestTemplate restTemplate, String rootUri) { |
||||
Assert.notNull(restTemplate, "RestTemplate must not be null"); |
||||
RootUriBuilderFactory handler = new RootUriBuilderFactory(rootUri, restTemplate.getUriTemplateHandler()); |
||||
restTemplate.setUriTemplateHandler(handler); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
/* |
||||
* Copyright 2012-2024 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.client; |
||||
|
||||
import java.net.URI; |
||||
import java.net.URISyntaxException; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.web.util.UriBuilder; |
||||
import org.springframework.web.util.UriBuilderFactory; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link RootUriBuilderFactory}. |
||||
* |
||||
* @author Scott Frederick |
||||
*/ |
||||
class RootUriBuilderFactoryTests { |
||||
|
||||
@Test |
||||
void uriStringPrefixesRoot() throws URISyntaxException { |
||||
UriBuilderFactory builderFactory = new RootUriBuilderFactory("https://example.com"); |
||||
UriBuilder builder = builderFactory.uriString("/hello"); |
||||
assertThat(builder.build()).isEqualTo(new URI("https://example.com/hello")); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue