Merge branch '7.0.x'

This commit is contained in:
Brian Clozel
2026-03-31 11:47:41 +02:00
38 changed files with 375 additions and 488 deletions
@@ -33,9 +33,9 @@ import org.springframework.web.client.support.RestGatewaySupport;
/**
* <strong>Main entry point for client-side REST testing</strong>. Used for tests
* that involve direct or indirect use of the {@link RestTemplate}. Provides a
* that involve direct or indirect use of the {@link RestClient}. Provides a
* way to set up expected requests that will be performed through the
* {@code RestTemplate} as well as mock responses to send back thus removing the
* {@code RestClient} as well as mock responses to send back thus removing the
* need for an actual server.
*
* <p>Below is an example that assumes static imports from
@@ -43,13 +43,14 @@ import org.springframework.web.client.support.RestGatewaySupport;
* and {@code ExpectedCount}:
*
* <pre class="code">
* RestTemplate restTemplate = new RestTemplate()
* MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();
* RestClient.Builder clientBuilder = RestClient.builder();
* MockRestServiceServer server = MockRestServiceServer.bindTo(clientBuilder).build();
* RestClient restClient = clientBuilder.build();
*
* server.expect(manyTimes(), requestTo("/hotels/42")).andExpect(method(HttpMethod.GET))
* .andRespond(withSuccess("{ \"id\" : \"42\", \"name\" : \"Holiday Inn\"}", MediaType.APPLICATION_JSON));
*
* Hotel hotel = restTemplate.getForObject("/hotels/{id}", Hotel.class, 42);
* Hotel hotel = restClient.get().uri("/hotels/{id}", 42).retrieve().body(Hotel.class);
* &#47;&#47; Use the hotel instance...
*
* // Verify all expectations met
@@ -167,6 +168,16 @@ public final class MockRestServiceServer {
}
/**
* A shortcut for {@code bindTo(clientBuilder).build()}.
* @param clientBuilder the RestClient builder to set up for mock testing
* @return the mock server
* @since 7.0.7
*/
public static MockRestServiceServer createServer(RestClient.Builder clientBuilder) {
return bindTo(clientBuilder).build();
}
/**
* A shortcut for {@code bindTo(restTemplate).build()}.
* @param restTemplate the RestTemplate to set up for mock testing
@@ -32,12 +32,13 @@ import org.springframework.util.StreamUtils;
* {@code ResponseCreator} that obtains the response by executing the request
* through a {@link ClientHttpRequestFactory}. This is useful in scenarios with
* multiple remote services where some need to be called rather than mocked.
* <p>The {@code ClientHttpRequestFactory} is typically obtained from the
* {@code RestTemplate} before it is passed to {@code MockRestServiceServer},
* <p>The {@code ClientHttpRequestFactory} is typically used for building the
* {@code RestClient} and is passed to {@code MockRestServiceServer},
* in effect using the original factory rather than the test factory:
* <pre><code>
* ResponseCreator withActualResponse = new ExecutingResponseCreator(restTemplate);
* MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();
* RestClient.Builder restClientBuilder = RestClient.builder().requestFactory(requestFactory);
* ResponseCreator withActualResponse = new ExecutingResponseCreator(requestFactory);
* MockRestServiceServer server = MockRestServiceServer.bindTo(restClientBuilder).build();
* //...
* server.expect(requestTo("/foo")).andRespond(withSuccess());
* server.expect(requestTo("/bar")).andRespond(withActualResponse);
@@ -30,7 +30,7 @@ import org.springframework.mock.http.client.MockClientHttpRequest;
import org.springframework.mock.http.client.MockClientHttpResponse;
import org.springframework.test.web.client.MockRestServiceServer.MockRestServiceServerBuilder;
import org.springframework.test.web.client.response.ExecutingResponseCreator;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -49,65 +49,72 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
*/
class MockRestServiceServerTests {
private final RestTemplate restTemplate = new RestTemplate();
private final RestClient.Builder clientBuilder = RestClient.builder();
@Test
void buildMultipleTimes() {
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(this.restTemplate);
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(this.clientBuilder);
MockRestServiceServer server = builder.build();
RestClient restClient = this.clientBuilder.build();
server.expect(requestTo("/foo")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/foo").retrieve().toBodilessEntity();
server.verify();
server = builder.ignoreExpectOrder(true).build();
restClient = this.clientBuilder.build();
server.expect(requestTo("/foo")).andRespond(withSuccess());
server.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/bar", Void.class);
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/bar").retrieve().toBodilessEntity();
restClient.get().uri("/foo").retrieve().toBodilessEntity();
server.verify();
server = builder.build();
restClient = this.clientBuilder.build();
server.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/bar", Void.class);
restClient.get().uri("/bar").retrieve().toBodilessEntity();
server.verify();
}
@Test
void exactExpectOrder() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate)
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder)
.ignoreExpectOrder(false).build();
RestClient restClient = this.clientBuilder.build();
server.expect(requestTo("/foo")).andRespond(withSuccess());
server.expect(requestTo("/bar")).andRespond(withSuccess());
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
this.restTemplate.getForObject("/bar", Void.class));
restClient.get().uri("/bar").retrieve().toBodilessEntity());
}
@Test
void ignoreExpectOrder() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate)
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder)
.ignoreExpectOrder(true).build();
RestClient restClient = this.clientBuilder.build();
server.expect(requestTo("/foo")).andRespond(withSuccess());
server.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/bar", Void.class);
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/bar").retrieve().toBodilessEntity();
restClient.get().uri("/foo").retrieve().toBodilessEntity();
server.verify();
}
@Test
void executingResponseCreator() {
RestTemplate restTemplate = createEchoRestTemplate();
ExecutingResponseCreator withActualCall = new ExecutingResponseCreator(restTemplate.getRequestFactory());
ClientHttpRequestFactory clientRequestFactory = createEchoClientRequestFactory();
ExecutingResponseCreator withActualCall = new ExecutingResponseCreator(clientRequestFactory);
this.clientBuilder.requestFactory(clientRequestFactory);
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder).build();
RestClient restClient = this.clientBuilder.build();
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();
server.expect(requestTo("/profile")).andRespond(withSuccess());
server.expect(requestTo("/quoteOfTheDay")).andRespond(withActualCall);
var response1 = restTemplate.getForEntity("/profile", String.class);
var response2 = restTemplate.getForEntity("/quoteOfTheDay", String.class);
var response1 = restClient.get().uri("/profile").retrieve().toEntity(String.class);
var response2 = restClient.get().uri("/quoteOfTheDay").retrieve().toEntity(String.class);
server.verify();
assertThat(response1.getStatusCode().value()).isEqualTo(200);
@@ -116,8 +123,8 @@ class MockRestServiceServerTests {
assertThat(response2.getBody()).isEqualTo("echo from /quoteOfTheDay");
}
private static RestTemplate createEchoRestTemplate() {
ClientHttpRequestFactory requestFactory = (uri, httpMethod) -> {
private static ClientHttpRequestFactory createEchoClientRequestFactory() {
return (uri, httpMethod) -> {
MockClientHttpRequest request = new MockClientHttpRequest(httpMethod, uri);
ClientHttpResponse response = new MockClientHttpResponse(
("echo from " + uri.getPath()).getBytes(StandardCharsets.UTF_8),
@@ -126,61 +133,64 @@ class MockRestServiceServerTests {
request.setResponse(response);
return request;
};
return new RestTemplate(requestFactory);
}
@Test
void resetAndReuseServer() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate).build();
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder).build();
RestClient restClient = this.clientBuilder.build();
server.expect(requestTo("/foo")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/foo").retrieve().toBodilessEntity();
server.verify();
server.reset();
server.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/bar", Void.class);
restClient.get().uri("/bar").retrieve().toBodilessEntity();
server.verify();
}
@Test
void resetAndReuseServerWithUnorderedExpectationManager() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate)
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder)
.ignoreExpectOrder(true).build();
RestClient restClient = this.clientBuilder.build();
server.expect(requestTo("/foo")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/foo").retrieve().toBodilessEntity();
server.verify();
server.reset();
server.expect(requestTo("/foo")).andRespond(withSuccess());
server.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/bar", Void.class);
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/bar").retrieve().toBodilessEntity();
restClient.get().uri("/foo").retrieve().toBodilessEntity();
server.verify();
}
@Test // gh-24486
void resetClearsRequestFailures() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate).build();
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder).build();
RestClient restClient = this.clientBuilder.build();
server.expect(once(), requestTo("/remoteurl")).andRespond(withSuccess());
this.restTemplate.postForEntity("/remoteurl", null, String.class);
restClient.post().uri("/remoteurl").retrieve().body(String.class);
server.verify();
assertThatExceptionOfType(AssertionError.class)
.isThrownBy(() -> this.restTemplate.postForEntity("/remoteurl", null, String.class))
.isThrownBy(() -> restClient.post().uri("/remoteurl").retrieve().body(String.class))
.withMessageStartingWith("No further requests expected");
server.reset();
server.expect(once(), requestTo("/remoteurl")).andRespond(withSuccess());
this.restTemplate.postForEntity("/remoteurl", null, String.class);
restClient.post().uri("/remoteurl").retrieve().body(String.class);
server.verify();
}
@Test // SPR-16132
void followUpRequestAfterFailure() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate).build();
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder).build();
RestClient restClient = this.clientBuilder.build();
server.expect(requestTo("/some-service/some-endpoint"))
.andRespond(request -> { throw new SocketException("pseudo network error"); });
@@ -189,11 +199,11 @@ class MockRestServiceServerTests {
.andExpect(method(POST)).andRespond(withSuccess());
try {
this.restTemplate.getForEntity("/some-service/some-endpoint", String.class);
restClient.get().uri("/some-service/some-endpoint").retrieve().body(String.class);
fail("Expected exception");
}
catch (Exception ex) {
this.restTemplate.postForEntity("/reporting-service/report-error", ex.toString(), String.class);
restClient.post().uri("/reporting-service/report-error").retrieve().body(String.class);
}
server.verify();
@@ -201,12 +211,13 @@ class MockRestServiceServerTests {
@Test // gh-21799
void verifyShouldFailIfRequestsFailed() {
MockRestServiceServer server = MockRestServiceServer.bindTo(this.restTemplate).build();
MockRestServiceServer server = MockRestServiceServer.bindTo(this.clientBuilder).build();
server.expect(once(), requestTo("/remoteurl")).andRespond(withSuccess());
RestClient restClient = this.clientBuilder.build();
this.restTemplate.postForEntity("/remoteurl", null, String.class);
restClient.post().uri("/remoteurl").retrieve().body(String.class);
assertThatExceptionOfType(AssertionError.class)
.isThrownBy(() -> this.restTemplate.postForEntity("/remoteurl", null, String.class))
.isThrownBy(() -> restClient.post().uri("/remoteurl").retrieve().body(String.class))
.withMessageStartingWith("No further requests expected");
assertThatExceptionOfType(AssertionError.class)
@@ -216,24 +227,26 @@ class MockRestServiceServerTests {
@Test
void verifyWithTimeout() {
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(this.restTemplate);
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(this.clientBuilder);
MockRestServiceServer server1 = builder.build();
RestClient restClient = this.clientBuilder.build();
server1.expect(requestTo("/foo")).andRespond(withSuccess());
server1.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);
restClient.get().uri("/foo").retrieve().toBodilessEntity();
assertThatThrownBy(() -> server1.verify(Duration.ofMillis(100))).hasMessage("""
Further request(s) expected leaving 1 unsatisfied expectation(s).
1 request(s) executed:
GET /foo, headers: [Accept:"application/json, application/*+json"]
GET /foo
""");
MockRestServiceServer server2 = builder.build();
restClient = this.clientBuilder.build();
server2.expect(requestTo("/foo")).andRespond(withSuccess());
server2.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);
this.restTemplate.getForObject("/bar", Void.class);
restClient.get().uri("/foo").retrieve().toBodilessEntity();
restClient.get().uri("/bar").retrieve().toBodilessEntity();
server2.verify(Duration.ofMillis(100));
}
@@ -17,8 +17,8 @@
package org.springframework.test.web.client.samples;
import java.io.IOException;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;
@@ -32,7 +32,7 @@ import org.springframework.http.client.ClientHttpResponse;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -46,17 +46,24 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
/**
* Examples to demonstrate writing client-side REST tests with Spring MVC Test.
*
* <p>While the tests in this class invoke the RestTemplate directly, in actual
* tests the RestTemplate may likely be invoked indirectly, i.e. through client
* <p>While the tests in this class invoke the RestClient directly, in actual
* tests the RestClient may likely be invoked indirectly, i.e. through client
* code.
*
* @author Rossen Stoyanchev
*/
class SampleTests {
private final RestTemplate restTemplate = new RestTemplate();
private RestClient restClient;
private final MockRestServiceServer mockServer = MockRestServiceServer.bindTo(this.restTemplate).ignoreExpectOrder(true).build();
private MockRestServiceServer mockServer;
@BeforeEach
void setup() {
RestClient.Builder clientBuilder = RestClient.builder();
this.mockServer = MockRestServiceServer.bindTo(clientBuilder).ignoreExpectOrder(true).build();
this.restClient = clientBuilder.build();
}
@Test
@@ -67,7 +74,7 @@ class SampleTests {
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
@SuppressWarnings("unused")
Person ludwig = this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
Person ludwig = this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
// We are only validating the request. The response is mocked out.
// hotel.getId() == 42
@@ -84,15 +91,15 @@ class SampleTests {
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
@SuppressWarnings("unused")
Person ludwig = this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
Person ludwig = this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
// We are only validating the request. The response is mocked out.
// hotel.getId() == 42
// hotel.getName().equals("Holiday Inn")
this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
this.mockServer.verify();
}
@@ -106,7 +113,7 @@ class SampleTests {
this.mockServer.expect(never(), requestTo("/composers/43")).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
this.mockServer.verify();
}
@@ -120,9 +127,9 @@ class SampleTests {
this.mockServer.expect(never(), requestTo("/composers/43")).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
this.restTemplate.getForObject("/composers/{id}", Person.class, 43));
this.restClient.get().uri("/composers/{id}", 43).retrieve().body(Person.class));
}
@Test
@@ -133,7 +140,7 @@ class SampleTests {
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
@SuppressWarnings("unused")
Person ludwig = this.restTemplate.getForObject("/composers/{id}", Person.class, 42);
Person ludwig = this.restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
// hotel.getId() == 42
// hotel.getName().equals("Holiday Inn")
@@ -156,11 +163,11 @@ class SampleTests {
.andRespond(withSuccess("8", MediaType.TEXT_PLAIN));
@SuppressWarnings("unused")
String result1 = this.restTemplate.getForObject("/number", String.class);
String result1 = this.restClient.get().uri("/number").retrieve().body(String.class);
// result1 == "1"
@SuppressWarnings("unused")
String result2 = this.restTemplate.getForObject("/number", String.class);
String result2 = this.restClient.get().uri("/number").retrieve().body(String.class);
// result == "2"
try {
@@ -175,18 +182,17 @@ class SampleTests {
void repeatedAccessToResponseViaResource() {
Resource resource = new ClassPathResource("ludwig.json", getClass());
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(new ContentInterceptor(resource)));
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate)
RestClient.Builder clientBuilder = RestClient.builder().requestInterceptor(new ContentInterceptor(resource));
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(clientBuilder)
.ignoreExpectOrder(true)
.bufferContent() // enable repeated reads of response body
.build();
RestClient restClient = clientBuilder.build();
mockServer.expect(requestTo("/composers/42")).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(resource, MediaType.APPLICATION_JSON));
restTemplate.getForObject("/composers/{id}", Person.class, 42);
restClient.get().uri("/composers/{id}", 42).retrieve().body(Person.class);
mockServer.verify();
}
@@ -16,17 +16,12 @@
package org.springframework.test.web.client.samples.matchers;
import java.net.URI;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.hamcrest.Matchers.startsWith;
@@ -44,15 +39,16 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
*/
class ContentRequestMatchersIntegrationTests {
private final RestTemplate restTemplate = new RestTemplate();
private RestClient restClient;
private final MockRestServiceServer mockServer = MockRestServiceServer.createServer(this.restTemplate);
private MockRestServiceServer mockServer;
@BeforeEach
void setup() {
this.restTemplate.setMessageConverters(
List.of(new StringHttpMessageConverter(), new JacksonJsonHttpMessageConverter()));
RestClient.Builder clientBuilder = RestClient.builder();
this.mockServer = MockRestServiceServer.createServer(clientBuilder);
this.restClient = clientBuilder.build();
}
@@ -89,7 +85,7 @@ class ContentRequestMatchersIntegrationTests {
}
private void executeAndVerify(Object body) {
this.restTemplate.put(URI.create("/foo"), body);
this.restClient.put().uri("/foo").body(body).retrieve().toBodilessEntity();
this.mockServer.verify();
}
@@ -16,18 +16,13 @@
package org.springframework.test.web.client.samples.matchers;
import java.net.URI;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
@@ -43,22 +38,23 @@ class HeaderRequestMatchersIntegrationTests {
private static final String RESPONSE_BODY = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}";
private final RestTemplate restTemplate = new RestTemplate();
private RestClient restClient;
private final MockRestServiceServer mockServer = MockRestServiceServer.createServer(this.restTemplate);
private MockRestServiceServer mockServer;
@BeforeEach
void setup() {
this.restTemplate.setMessageConverters(
List.of(new StringHttpMessageConverter(), new JacksonJsonHttpMessageConverter()));
RestClient.Builder clientBuilder = RestClient.builder();
this.mockServer = MockRestServiceServer.createServer(clientBuilder);
this.restClient = clientBuilder.build();
}
@Test
void string() {
this.mockServer.expect(requestTo("/person/1"))
.andExpect(header("Accept", "application/json, application/*+json"))
.andExpect(header("Accept", "application/json"))
.andRespond(withSuccess(RESPONSE_BODY, MediaType.APPLICATION_JSON));
executeAndVerify();
@@ -74,7 +70,7 @@ class HeaderRequestMatchersIntegrationTests {
}
private void executeAndVerify() {
this.restTemplate.getForObject(URI.create("/person/1"), Person.class);
this.restClient.get().uri("/person/1").accept(MediaType.APPLICATION_JSON).retrieve().body(Person.class);
this.mockServer.verify();
}
@@ -16,18 +16,17 @@
package org.springframework.test.web.client.samples.matchers;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
import org.springframework.http.MediaType;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
@@ -64,10 +63,16 @@ class JsonPathRequestMatchersIntegrationTests {
}
private final RestTemplate restTemplate =
new RestTemplate(Collections.singletonList(new JacksonJsonHttpMessageConverter()));
private RestClient restClient;
private final MockRestServiceServer mockServer = MockRestServiceServer.createServer(this.restTemplate);
private MockRestServiceServer mockServer;
@BeforeEach
void setup() {
RestClient.Builder clientBuilder = RestClient.builder();
this.mockServer = MockRestServiceServer.createServer(clientBuilder);
this.restClient = clientBuilder.build();
}
@Test
@@ -179,7 +184,8 @@ class JsonPathRequestMatchersIntegrationTests {
}
private void executeAndVerify() {
this.restTemplate.put(URI.create("/composers"), people);
this.restClient.put().uri("/composers").contentType(MediaType.APPLICATION_JSON)
.body(people).retrieve().toBodilessEntity();
this.mockServer.verify();
}
@@ -16,8 +16,6 @@
package org.springframework.test.web.client.samples.matchers;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -29,11 +27,11 @@ import jakarta.xml.bind.annotation.XmlRootElement;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.hamcrest.Matchers.hasXPath;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
@@ -61,7 +59,7 @@ class XmlContentRequestMatchersIntegrationTests {
private MockRestServiceServer mockServer;
private RestTemplate restTemplate;
private RestClient restClient;
private PeopleWrapper people;
@@ -76,13 +74,11 @@ class XmlContentRequestMatchersIntegrationTests {
this.people = new PeopleWrapper(composers);
List<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.add(new Jaxb2RootElementHttpMessageConverter());
RestClient.Builder clientBuilder = RestClient.builder().configureMessageConverters(converters ->
converters.registerDefaults().withXmlConverter(new Jaxb2RootElementHttpMessageConverter()));
this.restTemplate = new RestTemplate();
this.restTemplate.setMessageConverters(converters);
this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
this.mockServer = MockRestServiceServer.createServer(clientBuilder);
this.restClient = clientBuilder.build();
}
@Test
@@ -106,7 +102,8 @@ class XmlContentRequestMatchersIntegrationTests {
}
private void executeAndVerify() {
this.restTemplate.put(URI.create("/composers"), this.people);
this.restClient.put().uri("/composers").contentType(MediaType.APPLICATION_XML)
.body(this.people).retrieve().toBodilessEntity();
this.mockServer.verify();
}
@@ -16,8 +16,6 @@
package org.springframework.test.web.client.samples.matchers;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -31,11 +29,11 @@ import jakarta.xml.bind.annotation.XmlRootElement;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.equalTo;
@@ -61,7 +59,7 @@ class XpathRequestMatchersIntegrationTests {
private MockRestServiceServer mockServer;
private RestTemplate restTemplate;
private RestClient restClient;
private PeopleWrapper people;
@@ -80,13 +78,11 @@ class XpathRequestMatchersIntegrationTests {
this.people = new PeopleWrapper(composers, performers);
List<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.add(new Jaxb2RootElementHttpMessageConverter());
RestClient.Builder clientBuilder = RestClient.builder().configureMessageConverters(converters ->
converters.registerDefaults().withXmlConverter(new Jaxb2RootElementHttpMessageConverter()));
this.restTemplate = new RestTemplate();
this.restTemplate.setMessageConverters(converters);
this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
this.mockServer = MockRestServiceServer.createServer(clientBuilder);
this.restClient = clientBuilder.build();
}
@@ -190,7 +186,8 @@ class XpathRequestMatchersIntegrationTests {
}
private void executeAndVerify() {
this.restTemplate.put(URI.create("/composers"), this.people);
this.restClient.put().uri("/composers").contentType(MediaType.APPLICATION_XML)
.body(this.people).retrieve().toBodilessEntity();
this.mockServer.verify();
}
@@ -16,7 +16,6 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import java.time.Duration;
import reactor.core.publisher.Flux;
@@ -25,9 +24,7 @@ import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -51,8 +48,7 @@ class AsyncIntegrationTests extends AbstractHttpHandlerIntegrationTests {
void basicTest(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + port);
ResponseEntity<String> response = new RestTemplate().exchange(RequestEntity.get(url).build(), String.class);
ResponseEntity<String> response = getRestClient().get().retrieve().toEntity(String.class);
assertThat(response.getBody()).isEqualTo("hello");
}
@@ -16,7 +16,6 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -24,10 +23,8 @@ import java.util.Map;
import reactor.core.publisher.Mono;
import org.springframework.http.HttpCookie;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -52,10 +49,9 @@ class CookieIntegrationTests extends AbstractHttpHandlerIntegrationTests {
public void basicTest(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + port);
String header = "SID=31d4d96e407aad42; lang=en-US";
ResponseEntity<Void> response = new RestTemplate().exchange(
RequestEntity.get(url).header("Cookie", header).build(), Void.class);
ResponseEntity<Void> response = getRestClient().get()
.header("Cookie", "SID=31d4d96e407aad42; lang=en-US")
.retrieve().toBodilessEntity();
Map<String, List<HttpCookie>> requestCookies = this.cookieHandler.requestCookies;
assertThat(requestCookies).hasSize(2);
@@ -79,10 +75,9 @@ class CookieIntegrationTests extends AbstractHttpHandlerIntegrationTests {
public void partitionedAttributeTest(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + port);
String header = "SID=31d4d96e407aad42; lang=en-US";
ResponseEntity<Void> response = new RestTemplate().exchange(
RequestEntity.get(url).header("Cookie", header).build(), Void.class);
ResponseEntity<Void> response = getRestClient().get()
.header("Cookie", "SID=31d4d96e407aad42; lang=en-US")
.retrieve().toBodilessEntity();
List<String> headerValues = response.getHeaders().get("Set-Cookie");
assertThat(headerValues).hasSize(2);
@@ -97,10 +92,9 @@ class CookieIntegrationTests extends AbstractHttpHandlerIntegrationTests {
public void cookiesWithSameNameTest(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = new URI("http://localhost:" + port);
String header = "SID=31d4d96e407aad42; lang=en-US; lang=zh-CN";
new RestTemplate().exchange(
RequestEntity.get(url).header("Cookie", header).build(), Void.class);
ResponseEntity<Void> response = getRestClient().get()
.header("Cookie", "SID=31d4d96e407aad42; lang=en-US; lang=zh-CN")
.retrieve().toBodilessEntity();
Map<String, List<HttpCookie>> requestCookies = this.cookieHandler.requestCookies;
assertThat(requestCookies).hasSize(2);
@@ -16,14 +16,11 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import java.util.Random;
import reactor.core.publisher.Mono;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -49,11 +46,8 @@ class EchoHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
public void echo(HttpServer httpServer) throws Exception {
startServer(httpServer);
RestTemplate restTemplate = new RestTemplate();
byte[] body = randomBytes();
RequestEntity<byte[]> request = RequestEntity.post(URI.create("http://localhost:" + port)).body(body);
ResponseEntity<byte[]> response = restTemplate.exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().post().body(body).retrieve().toEntity(byte[].class);
assertThat(response.getBody()).isEqualTo(body);
}
@@ -21,10 +21,9 @@ import java.net.URI;
import reactor.core.publisher.Mono;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.NoOpResponseErrorHandler;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyCoreHttpServer;
@@ -37,8 +36,6 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class ErrorHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
private static final ResponseErrorHandler NO_OP_ERROR_HANDLER = new NoOpResponseErrorHandler();
private final ErrorHandler handler = new ErrorHandler();
@@ -47,16 +44,20 @@ class ErrorHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
return handler;
}
@Override
protected RestClient initRestClient(RestClient.Builder builder) {
return builder
.defaultStatusHandler(HttpStatusCode::is5xxServerError, (req, res) -> {})
.defaultStatusHandler(HttpStatusCode::is4xxClientError, (req, res) -> {})
.build();
}
@ParameterizedHttpServerTest
void responseBodyError(HttpServer httpServer) throws Exception {
startServer(httpServer);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(NO_OP_ERROR_HANDLER);
URI url = URI.create("http://localhost:" + port + "/response-body-error");
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
ResponseEntity<String> response = getRestClient().get().uri("/response-body-error")
.retrieve().toEntity(String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
}
@@ -65,11 +66,8 @@ class ErrorHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
void handlingError(HttpServer httpServer) throws Exception {
startServer(httpServer);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(NO_OP_ERROR_HANDLER);
URI url = URI.create("http://localhost:" + port + "/handling-error");
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
ResponseEntity<String> response = getRestClient().get().uri("/handling-error")
.retrieve().toEntity(String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
}
@@ -78,11 +76,10 @@ class ErrorHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
void emptyPathSegments(HttpServer httpServer) throws Exception {
startServer(httpServer);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(NO_OP_ERROR_HANDLER);
URI url = URI.create("http://localhost:" + port + "//");
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
ResponseEntity<String> response = getRestClient().get()
.uri(URI.create("http://localhost:" + this.server.getPort() + "//"))
.retrieve().toEntity(String.class);
// Jetty 10+ rejects empty path segments, see https://github.com/eclipse/jetty.project/issues/6302,
// but an application can apply CompactPathRule via RewriteHandler:
@@ -16,8 +16,6 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@@ -27,14 +25,12 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.codec.multipart.FormFieldPart;
import org.springframework.http.codec.multipart.Part;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
import org.springframework.web.server.adapter.HttpWebHandlerAdapter;
@@ -81,9 +77,9 @@ class MultipartHttpHandlerIntegrationTests extends AbstractHttpHandlerIntegratio
parts.add("fooPart", fooPart);
parts.add("barPart", barPart);
URI url = URI.create("http://localhost:" + port + "/form-parts");
ResponseEntity<Void> response = new RestTemplate().exchange(
RequestEntity.post(url).contentType(mediaType).body(parts), Void.class);
ResponseEntity<Void> response = getRestClient().post().uri("/form-parts")
.contentType(MediaType.MULTIPART_FORM_DATA).body(parts)
.retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -16,7 +16,6 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import java.util.Random;
import org.reactivestreams.Publisher;
@@ -25,9 +24,7 @@ import reactor.core.publisher.Mono;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -59,11 +56,7 @@ class RandomHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests
// TODO: fix Reactor support
RestTemplate restTemplate = new RestTemplate();
byte[] body = randomBytes();
RequestEntity<byte[]> request = RequestEntity.post(URI.create("http://localhost:" + port)).body(body);
ResponseEntity<byte[]> response = restTemplate.exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().post().body(randomBytes()).retrieve().toEntity(byte[].class);
assertThat(response.getBody()).isNotNull();
assertThat(response.getHeaders().getContentLength()).isEqualTo(RESPONSE_SIZE);
@@ -21,9 +21,7 @@ import java.net.URI;
import reactor.core.publisher.Mono;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -44,9 +42,7 @@ class ServerHttpRequestIntegrationTests extends AbstractHttpHandlerIntegrationTe
void checkUri(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + port + "/foo?param=bar");
RequestEntity<Void> request = RequestEntity.post(url).build();
ResponseEntity<Void> response = new RestTemplate().exchange(request, Void.class);
ResponseEntity<Void> response = getRestClient().post().uri("/foo?param=bar").retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -32,10 +32,9 @@ import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.ReactorHttpsServer;
@@ -52,10 +51,7 @@ class ServerHttpsRequestIntegrationTests {
private final HttpServer server = new ReactorHttpsServer();
private int port;
private RestTemplate restTemplate;
private RestClient restClient;
@BeforeEach
void startServer() throws Exception {
@@ -63,8 +59,6 @@ class ServerHttpsRequestIntegrationTests {
this.server.afterPropertiesSet();
this.server.start();
// Set dynamically chosen port
this.port = this.server.getPort();
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(new TrustSelfSignedStrategy());
@@ -77,7 +71,8 @@ class ServerHttpsRequestIntegrationTests {
setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpclient);
this.restTemplate = new RestTemplate(requestFactory);
this.restClient = RestClient.builder().baseUrl("https://localhost:" + this.server.getPort())
.requestFactory(requestFactory).build();
}
@AfterEach
@@ -87,9 +82,7 @@ class ServerHttpsRequestIntegrationTests {
@Test
void checkUri() {
URI url = URI.create("https://localhost:" + port + "/foo?param=bar");
RequestEntity<Void> request = RequestEntity.post(url).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
ResponseEntity<Void> response = this.restClient.post().uri("/foo?param=bar").retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -16,7 +16,6 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Random;
@@ -24,9 +23,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -54,12 +51,9 @@ class WriteOnlyHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTes
void writeOnly(HttpServer httpServer) throws Exception {
startServer(httpServer);
RestTemplate restTemplate = new RestTemplate();
this.body = randomBytes();
RequestEntity<byte[]> request = RequestEntity.post(URI.create("http://localhost:" + port))
.body("".getBytes(StandardCharsets.UTF_8));
ResponseEntity<byte[]> response = restTemplate.exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().post().body("".getBytes(StandardCharsets.UTF_8))
.retrieve().toEntity(byte[].class);
assertThat(response.getBody()).isEqualTo(body);
}
@@ -17,17 +17,14 @@
package org.springframework.http.server.reactive;
import java.io.File;
import java.net.URI;
import reactor.core.publisher.Mono;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.ZeroCopyHttpOutputMessage;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.JettyCoreHttpServer;
@@ -59,9 +56,7 @@ class ZeroCopyIntegrationTests extends AbstractHttpHandlerIntegrationTests {
startServer(httpServer);
URI url = URI.create("http://localhost:" + port);
RequestEntity<?> request = RequestEntity.get(url).build();
ResponseEntity<byte[]> response = new RestTemplate().exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().get().retrieve().toEntity(byte[].class);
assertThat(response.hasBody()).isTrue();
assertThat(response.getHeaders().getContentLength()).isEqualTo(springLogoResource.contentLength());
@@ -38,11 +38,12 @@ import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.context.request.ServletWebRequest;
import static org.assertj.core.api.Assertions.assertThat;
@@ -58,12 +59,10 @@ class WebRequestDataBinderIntegrationTests {
private final PartListServlet partListServlet = new PartListServlet();
private final RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
private RestClient restClient;
private Server jettyServer;
private String baseUrl;
private Path tempDirectory;
@@ -91,7 +90,8 @@ class WebRequestDataBinderIntegrationTests {
Connector[] connectors = jettyServer.getConnectors();
NetworkConnector connector = (NetworkConnector) connectors[0];
baseUrl = "http://localhost:" + connector.getLocalPort();
this.restClient = RestClient.builder().baseUrl("http://localhost:" + connector.getLocalPort())
.requestFactory(new HttpComponentsClientHttpRequestFactory()).build();
}
@AfterAll
@@ -117,7 +117,9 @@ class WebRequestDataBinderIntegrationTests {
parts.add("firstPart", firstPart);
parts.add("secondPart", "secondValue");
template.postForLocation(baseUrl + "/parts", parts);
this.restClient.post().uri("/parts")
.contentType(MediaType.MULTIPART_FORM_DATA).body(parts)
.retrieve().toBodilessEntity();
assertThat(bean.getFirstPart()).isNotNull();
assertThat(bean.getSecondPart()).isNotNull();
@@ -134,7 +136,9 @@ class WebRequestDataBinderIntegrationTests {
Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg");
parts.add("partList", logo);
template.postForLocation(baseUrl + "/partlist", parts);
this.restClient.post().uri("/partlist")
.contentType(MediaType.MULTIPART_FORM_DATA).body(parts)
.retrieve().toBodilessEntity();
assertThat(bean.getPartList()).isNotNull();
assertThat(bean.getPartList()).hasSize(parts.get("partList").size());
@@ -35,6 +35,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
@@ -49,6 +50,7 @@ import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
@@ -135,15 +137,15 @@ class RestClientObservationTests {
@Test
void shouldContributeServerErrorOutcome() throws Exception {
ResponseErrorHandler errorHandler = mock();
given(errorHandler.hasError(response)).willReturn(true);
this.client = this.client.mutate().defaultStatusHandler(errorHandler).build();
RestClient.ResponseSpec.ErrorHandler errorHandler = mock();
this.client = this.client.mutate()
.defaultStatusHandler(HttpStatusCode::is5xxServerError, errorHandler).build();
String url = "https://example.org";
mockSentRequest(GET, url);
mockResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR);
willThrow(new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR))
.given(errorHandler).handleError(URI.create(url), GET, response);
.given(errorHandler).handle(any(), any());
assertThatExceptionOfType(HttpServerErrorException.class).isThrownBy(() ->
client.get().uri(url).retrieve().toBodilessEntity());
@@ -257,7 +259,8 @@ class RestClientObservationTests {
@Test
void openScopeWithObservation() throws Exception {
this.client = createBuilder().requestInterceptor(new ObservationContextInterceptor(this.observationRegistry))
.defaultStatusHandler(new ObservationErrorHandler(this.observationRegistry)).build();
.defaultStatusHandler(HttpStatusCode::is2xxSuccessful, new ObservationErrorHandler(this.observationRegistry))
.build();
mockSentRequest(GET, "https://example.org");
mockResponseStatus(HttpStatus.OK);
mockResponseBody("Hello World", MediaType.TEXT_PLAIN);
@@ -334,7 +337,7 @@ class RestClientObservationTests {
}
}
static class ObservationErrorHandler implements ResponseErrorHandler {
static class ObservationErrorHandler implements RestClient.ResponseSpec.ErrorHandler {
final TestObservationRegistry observationRegistry;
@@ -343,14 +346,10 @@ class RestClientObservationTests {
}
@Override
public boolean hasError(ClientHttpResponse response) {
return true;
}
@Override
public void handleError(URI uri, HttpMethod httpMethod, ClientHttpResponse response) {
public void handle(HttpRequest request, ClientHttpResponse response) throws IOException {
assertThat(this.observationRegistry.getCurrentObservationScope()).isNotNull();
}
}
}
@@ -16,7 +16,6 @@
package org.springframework.web.server.session;
import java.net.URI;
import java.time.Clock;
import java.time.Duration;
import java.util.List;
@@ -26,10 +25,8 @@ import reactor.core.publisher.Mono;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
import org.springframework.web.server.WebSession;
@@ -47,8 +44,6 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
private final RestTemplate restTemplate = new RestTemplate();
private final DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
private final TestWebHandler handler = new TestWebHandler();
@@ -64,16 +59,14 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
public void createSession(HttpServer httpServer) throws Exception {
startServer(httpServer);
RequestEntity<Void> request = RequestEntity.get(createUri()).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
ResponseEntity<Void> response = getRestClient().get().retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String id = extractSessionId(response.getHeaders());
assertThat(id).isNotNull();
assertThat(this.handler.getSessionRequestCount()).isEqualTo(1);
request = RequestEntity.get(createUri()).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
response = getRestClient().get().cookie("SESSION", id).retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getHeaders().get("Set-Cookie")).isNull();
@@ -85,8 +78,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
startServer(httpServer);
// First request: no session yet, new session created
RequestEntity<Void> request = RequestEntity.get(createUri()).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
ResponseEntity<Void> response = getRestClient().get().retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String id = extractSessionId(response.getHeaders());
@@ -94,8 +86,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
assertThat(this.handler.getSessionRequestCount()).isEqualTo(1);
// Second request: same session
request = RequestEntity.get(createUri()).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
response = getRestClient().get().cookie("SESSION", id).retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getHeaders().get("Set-Cookie")).isNull();
@@ -108,8 +99,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
store.setClock(Clock.offset(store.getClock(), Duration.ofMinutes(31)));
// Third request: expired session, new session created
request = RequestEntity.get(createUri()).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
response = getRestClient().get().cookie("SESSION", id).retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
id = extractSessionId(response.getHeaders());
@@ -122,8 +112,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
startServer(httpServer);
// First request: no session yet, new session created
RequestEntity<Void> request = RequestEntity.get(createUri()).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
ResponseEntity<Void> response = getRestClient().get().retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String id = extractSessionId(response.getHeaders());
@@ -134,9 +123,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
store.setClock(Clock.offset(store.getClock(), Duration.ofMinutes(31)));
// Second request: session expires
URI uri = URI.create("http://localhost:" + this.port + "/?expire");
request = RequestEntity.get(uri).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
response = getRestClient().get().uri("/?expire").cookie("SESSION", id).retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String value = response.getHeaders().getFirst("Set-Cookie");
@@ -149,8 +136,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
startServer(httpServer);
// First request: no session yet, new session created
RequestEntity<Void> request = RequestEntity.get(createUri()).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
ResponseEntity<Void> response = getRestClient().get().retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String oldId = extractSessionId(response.getHeaders());
@@ -158,9 +144,7 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
assertThat(this.handler.getSessionRequestCount()).isEqualTo(1);
// Second request: session id changes
URI uri = URI.create("http://localhost:" + this.port + "/?changeId");
request = RequestEntity.get(uri).header("Cookie", "SESSION=" + oldId).build();
response = this.restTemplate.exchange(request, Void.class);
response = getRestClient().get().uri("/?changeId").cookie("SESSION", oldId).retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String newId = extractSessionId(response.getHeaders());
@@ -174,17 +158,14 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
startServer(httpServer);
// First request: no session yet, new session created
RequestEntity<Void> request = RequestEntity.get(createUri()).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
ResponseEntity<Void> response = getRestClient().get().retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String id = extractSessionId(response.getHeaders());
assertThat(id).isNotNull();
// Second request: invalidates session
URI uri = URI.create("http://localhost:" + this.port + "/?invalidate");
request = RequestEntity.get(uri).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
response = getRestClient().get().uri("/?invalidate").cookie("SESSION", id).retrieve().toBodilessEntity();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String value = response.getHeaders().getFirst("Set-Cookie");
@@ -205,10 +186,6 @@ class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
return null;
}
private URI createUri() {
return URI.create("http://localhost:" + this.port + "/");
}
private static class TestWebHandler implements WebHandler {
@@ -36,6 +36,7 @@ import reactor.core.publisher.Flux;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClient;
import static org.junit.jupiter.params.provider.Arguments.argumentSet;
@@ -75,6 +76,8 @@ public abstract class AbstractHttpHandlerIntegrationTests {
protected int port;
private RestClient restClient;
protected void startServer(HttpServer httpServer) throws Exception {
this.server = httpServer;
@@ -84,6 +87,7 @@ public abstract class AbstractHttpHandlerIntegrationTests {
// Set dynamically chosen port
this.port = this.server.getPort();
onServerStart(this.server.getPort());
}
@AfterEach
@@ -97,6 +101,18 @@ public abstract class AbstractHttpHandlerIntegrationTests {
protected abstract HttpHandler createHttpHandler();
protected void onServerStart(int port) {
this.restClient = initRestClient(RestClient.builder().baseUrl("http://localhost:" + this.port));
}
protected RestClient initRestClient(RestClient.Builder builder) {
return builder.build();
}
protected RestClient getRestClient() {
return this.restClient;
}
/**
* Return an interval stream of N number of ticks and buffer the emissions
@@ -29,7 +29,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@@ -37,7 +36,6 @@ import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.config.EnableWebFlux;
@@ -60,8 +58,6 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
*/
class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
private final RestTemplate restTemplate = new RestTemplate();
@Override
protected HttpHandler createHttpHandler() {
@@ -76,8 +72,8 @@ class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe
void mono(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<Person> result =
this.restTemplate.getForEntity("http://localhost:" + this.port + "/mono", Person.class);
ResponseEntity<Person> result = getRestClient().get().uri("http://localhost:" + this.port + "/mono")
.retrieve().toEntity(Person.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().getName()).isEqualTo("John");
@@ -87,10 +83,8 @@ class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe
void flux(HttpServer httpServer) throws Exception {
startServer(httpServer);
ParameterizedTypeReference<List<Person>> reference = new ParameterizedTypeReference<>() {};
ResponseEntity<List<Person>> result =
this.restTemplate
.exchange("http://localhost:" + this.port + "/flux", HttpMethod.GET, null, reference);
ResponseEntity<List<Person>> result = getRestClient().get().uri("http://localhost:" + this.port + "/flux")
.retrieve().toEntity(new ParameterizedTypeReference<>() {});
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
List<Person> body = result.getBody();
@@ -103,8 +97,8 @@ class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe
void controller(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<Person> result =
this.restTemplate.getForEntity("http://localhost:" + this.port + "/controller", Person.class);
ResponseEntity<Person> result = getRestClient().get().uri("http://localhost:" + this.port + "/controller")
.retrieve().toEntity(Person.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().getName()).isEqualTo("John");
@@ -114,9 +108,8 @@ class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe
void attributes(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
this.restTemplate
.getForEntity("http://localhost:" + this.port + "/attributes/bar", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + this.port + "/attributes/bar")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -125,8 +118,8 @@ class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe
void nested(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result = this.restTemplate
.getForEntity("http://localhost:" + this.port + "/foo/bar", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + this.port + "/foo/bar")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -25,7 +25,6 @@ import reactor.core.publisher.Mono;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
import org.springframework.web.util.pattern.PathPattern;
@@ -42,8 +41,6 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
*/
class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests {
private final RestTemplate restTemplate = new RestTemplate();
@Override
protected RouterFunction<?> routerFunction() {
@@ -64,8 +61,8 @@ class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests
void bar(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/foo/bar", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + port + "/foo/bar")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isEqualTo("/foo/bar");
@@ -75,8 +72,8 @@ class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests
void baz(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/foo/baz", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + port + "/foo/baz")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isEqualTo("/foo/baz");
@@ -86,8 +83,8 @@ class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests
void variables(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/1/2/3", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + port + "/1/2/3")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
String body = result.getBody();
@@ -102,8 +99,8 @@ class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests
void parentVariables(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/1/bar", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + port + "/1/bar")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isEqualTo("/{foo}/bar\n{foo=1}");
@@ -115,8 +112,8 @@ class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests
void removeFailedNestedPathVariables(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/qux/quux", String.class);
ResponseEntity<String> result = getRestClient().get().uri("http://localhost:" + port + "/qux/quux")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isEqualTo("/{qux}/quux\n{qux=qux}");
@@ -128,8 +125,8 @@ class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests
void removeFailedPathVariablesAnd(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.postForEntity("http://localhost:" + port + "/qux/quux", "", String.class);
ResponseEntity<String> result = getRestClient().post().uri("http://localhost:" + port + "/qux/quux")
.retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isEqualTo("{}");
@@ -16,7 +16,6 @@
package org.springframework.web.reactive.function.server;
import java.net.URI;
import java.util.List;
import java.util.Objects;
@@ -25,11 +24,8 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
import static org.assertj.core.api.Assertions.assertThat;
@@ -44,8 +40,6 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
*/
class PublisherHandlerFunctionIntegrationTests extends AbstractRouterFunctionIntegrationTests {
private final RestTemplate restTemplate = new RestTemplate();
@Override
protected RouterFunction<?> routerFunction() {
@@ -55,13 +49,11 @@ class PublisherHandlerFunctionIntegrationTests extends AbstractRouterFunctionInt
.and(route(GET("/flux"), personHandler::flux));
}
@ParameterizedHttpServerTest
void mono(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<Person> result =
restTemplate.getForEntity("http://localhost:" + super.port + "/mono", Person.class);
ResponseEntity<Person> result = getRestClient().get().uri("/mono").retrieve().toEntity(Person.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().getName()).isEqualTo("John");
@@ -71,9 +63,8 @@ class PublisherHandlerFunctionIntegrationTests extends AbstractRouterFunctionInt
void flux(HttpServer httpServer) throws Exception {
startServer(httpServer);
ParameterizedTypeReference<List<Person>> reference = new ParameterizedTypeReference<>() {};
ResponseEntity<List<Person>> result =
restTemplate.exchange("http://localhost:" + super.port + "/flux", HttpMethod.GET, null, reference);
ResponseEntity<List<Person>> result = getRestClient().get().uri("/flux").retrieve()
.toEntity(new ParameterizedTypeReference<>() {});
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
List<Person> body = result.getBody();
@@ -86,10 +77,8 @@ class PublisherHandlerFunctionIntegrationTests extends AbstractRouterFunctionInt
void postMono(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI uri = URI.create("http://localhost:" + super.port + "/mono");
Person person = new Person("Jack");
RequestEntity<Person> requestEntity = RequestEntity.post(uri).body(person);
ResponseEntity<Person> result = restTemplate.exchange(requestEntity, Person.class);
ResponseEntity<Person> result = getRestClient().post().uri("/mono").body(person).retrieve().toEntity(Person.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().getName()).isEqualTo("Jack");
@@ -31,7 +31,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.result.view.View;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange;
@@ -48,8 +47,6 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
*/
class RenderingResponseIntegrationTests extends AbstractRouterFunctionIntegrationTests {
private final RestTemplate restTemplate = new RestTemplate();
@Override
protected RouterFunction<?> routerFunction() {
@@ -76,8 +73,7 @@ class RenderingResponseIntegrationTests extends AbstractRouterFunctionIntegratio
void normal(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/normal", String.class);
ResponseEntity<String> result = getRestClient().get().uri("/normal").retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
Map<String, String> body = parseBody(result.getBody());
@@ -90,8 +86,7 @@ class RenderingResponseIntegrationTests extends AbstractRouterFunctionIntegratio
void filter(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/filter", String.class);
ResponseEntity<String> result = getRestClient().get().uri("/filter").retrieve().toEntity(String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
Map<String, String> body = parseBody(result.getBody());
@@ -16,7 +16,6 @@
package org.springframework.web.reactive.result;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -31,11 +30,9 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.server.WebHandler;
@@ -54,6 +51,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandlerIntegrationTests {
@Override
protected HttpHandler createHttpHandler() {
AnnotationConfigApplicationContext wac = new AnnotationConfigApplicationContext(WebConfig.class);
@@ -63,15 +61,12 @@ class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandlerIntegra
.build();
}
@ParameterizedHttpServerTest
void requestToFooHandler(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + this.port + "/foo");
RequestEntity<Void> request = RequestEntity.get(url).build();
@SuppressWarnings("resource")
ResponseEntity<byte[]> response = new RestTemplate().exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().get().uri("http://localhost:" + this.port + "/foo")
.retrieve().toEntity(byte[].class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo("foo".getBytes(StandardCharsets.UTF_8));
@@ -81,10 +76,8 @@ class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandlerIntegra
public void requestToBarHandler(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + this.port + "/bar");
RequestEntity<Void> request = RequestEntity.get(url).build();
@SuppressWarnings("resource")
ResponseEntity<byte[]> response = new RestTemplate().exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().get().uri("http://localhost:" + this.port + "/bar")
.retrieve().toEntity(byte[].class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo("bar".getBytes(StandardCharsets.UTF_8));
@@ -94,24 +87,19 @@ class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandlerIntegra
void requestToHeaderSettingHandler(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + this.port + "/header");
RequestEntity<Void> request = RequestEntity.get(url).build();
@SuppressWarnings("resource")
ResponseEntity<byte[]> response = new RestTemplate().exchange(request, byte[].class);
ResponseEntity<byte[]> response = getRestClient().get().uri("http://localhost:" + this.port + "/header")
.retrieve().toEntity(byte[].class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getHeaders().getFirst("foo")).isEqualTo("bar");
}
@ParameterizedHttpServerTest
@SuppressWarnings("resource")
void handlerNotFound(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI url = URI.create("http://localhost:" + this.port + "/oops");
RequestEntity<Void> request = RequestEntity.get(url).build();
try {
new RestTemplate().exchange(request, byte[].class);
getRestClient().get().uri("http://localhost:" + this.port + "/oops").retrieve().toEntity(byte[].class);
}
catch (HttpClientErrorException ex) {
assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
@@ -17,18 +17,14 @@
package org.springframework.web.reactive.result.method.annotation;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpHandlerIntegrationTests;
@@ -39,102 +35,74 @@ import org.springframework.web.testfixture.http.server.reactive.bootstrap.Abstra
*/
public abstract class AbstractRequestMappingIntegrationTests extends AbstractHttpHandlerIntegrationTests {
private RestTemplate restTemplate = new RestTemplate();
private ApplicationContext applicationContext;
@Override
protected HttpHandler createHttpHandler() {
this.restTemplate = initRestTemplate();
this.applicationContext = initApplicationContext();
return WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
}
protected abstract ApplicationContext initApplicationContext();
protected RestTemplate initRestTemplate() {
return new RestTemplate();
}
protected ApplicationContext getApplicationContext() {
return this.applicationContext;
}
protected RestTemplate getRestTemplate() {
return this.restTemplate;
}
<T> ResponseEntity<T> performGet(String url, MediaType out, Class<T> type) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(out));
return getRestTemplate().exchange(prepareGet(url, headers), type);
return getRestClient()
.get().uri(URI.create(url)).accept(out)
.retrieve()
.toEntity(type);
}
<T> ResponseEntity<T> performGet(String url, HttpHeaders headers, Class<T> type) {
return getRestTemplate().exchange(prepareGet(url, headers), type);
return getRestClient()
.get().uri(URI.create(url)).headers(httpHeaders -> httpHeaders.putAll(headers))
.retrieve()
.toEntity(type);
}
<T> ResponseEntity<T> performGet(String url, MediaType out, ParameterizedTypeReference<T> type) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(out));
return this.restTemplate.exchange(prepareGet(url, headers), type);
return getRestClient()
.get().uri(URI.create(url)).accept(out)
.retrieve()
.toEntity(type);
}
<T> ResponseEntity<T> performOptions(String url, HttpHeaders headers, Class<T> type) {
return getRestTemplate().exchange(prepareOptions(url, headers), type);
return getRestClient()
.options().uri(URI.create(url)).headers(httpHeaders -> httpHeaders.putAll(headers))
.retrieve()
.toEntity(type);
}
<T> ResponseEntity<T> performPost(String url, MediaType in, Object body, MediaType out, Class<T> type) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(in);
if (out != null) {
headers.setAccept(Collections.singletonList(out));
RestClient.RequestBodySpec bodySpec = getRestClient()
.post().uri(URI.create(url)).accept(out).contentType(in);
if (body != null) {
bodySpec.body(body);
}
return getRestTemplate().exchange(preparePost(url, headers, body), type);
return bodySpec.retrieve().toEntity(type);
}
<T> ResponseEntity<T> performPost(String url, HttpHeaders headers, Object body, Class<T> type) {
return getRestTemplate().exchange(preparePost(url, headers, body), type);
RestClient.RequestBodySpec bodySpec = getRestClient()
.post().uri(URI.create(url)).headers(httpHeaders -> httpHeaders.putAll(headers));
if (body != null) {
bodySpec.body(body);
}
return bodySpec.retrieve().toEntity(type);
}
<T> ResponseEntity<T> performPost(String url, MediaType in, Object body, MediaType out, ParameterizedTypeReference<T> type) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(in);
if (out != null) {
headers.setAccept(Collections.singletonList(out));
}
return getRestTemplate().exchange(preparePost(url, headers, body), type);
}
private RequestEntity<Void> prepareGet(String url, HttpHeaders headers) {
URI uri = URI.create("http://localhost:" + this.port + url);
RequestEntity.HeadersBuilder<?> builder = RequestEntity.get(uri);
addHeaders(builder, headers);
return builder.build();
}
private RequestEntity<Void> prepareOptions(String url, HttpHeaders headers) {
URI uri = URI.create("http://localhost:" + this.port + url);
RequestEntity.HeadersBuilder<?> builder = RequestEntity.options(uri);
addHeaders(builder, headers);
return builder.build();
}
private void addHeaders(RequestEntity.HeadersBuilder<?> builder, HttpHeaders headers) {
for (Map.Entry<String, List<String>> entry : headers.headerSet()) {
for (String value : entry.getValue()) {
builder.header(entry.getKey(), value);
}
}
}
private RequestEntity<?> preparePost(String url, HttpHeaders headers, Object body) {
URI uri = URI.create("http://localhost:" + this.port + url);
RequestEntity.BodyBuilder builder = RequestEntity.post(uri);
addHeaders(builder, headers);
return builder.body(body);
return getRestClient()
.post().uri(URI.create(url)).accept(out).contentType(in).body(body)
.retrieve()
.toEntity(type);
}
}
@@ -30,7 +30,7 @@ import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.AbstractHttpServer;
@@ -73,16 +73,13 @@ class ContextPathIntegrationTests {
server.start();
try {
RestTemplate restTemplate = new RestTemplate();
String actual;
RestClient restClient = RestClient.create("http://localhost:" + server.getPort());
String url = "http://localhost:" + server.getPort() + "/webApp1/test";
actual = restTemplate.getForObject(url, String.class);
assertThat(actual).isEqualTo("Tested in /webApp1");
assertThat(restClient.get().uri("/webApp1/test").retrieve().body(String.class))
.isEqualTo("Tested in /webApp1");
url = "http://localhost:" + server.getPort() + "/webApp2/test";
actual = restTemplate.getForObject(url, String.class);
assertThat(actual).isEqualTo("Tested in /webApp2");
assertThat(restClient.get().uri("/webApp2/test").retrieve().body(String.class))
.isEqualTo("Tested in /webApp2");
}
finally {
server.stop();
@@ -104,9 +101,9 @@ class ContextPathIntegrationTests {
server.start();
try {
String url = "http://localhost:" + server.getPort() + "/app/api/test";
String actual = new RestTemplate().getForObject(url, String.class);
assertThat(actual).isEqualTo("Tested in /app/api");
RestClient restClient = RestClient.create("http://localhost:" + server.getPort());
assertThat(restClient.get().uri("/app/api/test").retrieve().body(String.class))
.isEqualTo("Tested in /app/api");
}
finally {
server.stop();
@@ -35,7 +35,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -73,10 +73,11 @@ class CrossOriginAnnotationIntegrationTests extends AbstractRequestMappingIntegr
return context;
}
@Override
protected RestTemplate initRestTemplate() {
protected RestClient initRestClient(RestClient.Builder builder) {
// JDK default HTTP client disallowed headers like Origin
return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
return builder.requestFactory(new HttpComponentsClientHttpRequestFactory()).build();
}
@@ -29,7 +29,7 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurationSupport;
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
@@ -63,9 +63,9 @@ class GlobalCorsConfigIntegrationTests extends AbstractRequestMappingIntegration
}
@Override
protected RestTemplate initRestTemplate() {
protected RestClient initRestClient(RestClient.Builder builder) {
// JDK default HTTP client disallowed headers like Origin
return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
return builder.requestFactory(new HttpComponentsClientHttpRequestFactory()).build();
}
@@ -16,7 +16,6 @@
package org.springframework.web.reactive.result.method.annotation;
import java.net.URI;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
@@ -31,7 +30,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.GetMapping;
@@ -75,11 +73,8 @@ class RequestMappingIntegrationTests extends AbstractRequestMappingIntegrationTe
void emptyMapping(HttpServer httpServer) throws Exception {
startServer(httpServer);
String url = "http://localhost:" + this.port;
assertThat(getRestTemplate().getForObject(url, String.class)).isEqualTo("root");
url += "/";
assertThat(getRestTemplate().getForObject(url, String.class)).isEqualTo("root");
assertThat(getRestClient().get().retrieve().body(String.class)).isEqualTo("root");
assertThat(getRestClient().get().uri("/").retrieve().body(String.class)).isEqualTo("root");
assertThat(getApplicationContext().getBean(TestExecutor.class).invocationCount.get()).isEqualTo(4);
assertThat(getApplicationContext().getBean(TestPredicate.class).invocationCount.get()).isEqualTo(4);
@@ -89,9 +84,8 @@ class RequestMappingIntegrationTests extends AbstractRequestMappingIntegrationTe
void httpHead(HttpServer httpServer) throws Exception {
startServer(httpServer);
String url = "http://localhost:" + this.port + "/text";
HttpHeaders headers = getRestTemplate().headForHeaders(url);
String contentType = headers.getFirst("Content-Type");
ResponseEntity<Void> response = getRestClient().head().uri("/text").retrieve().toBodilessEntity();
String contentType = response.getHeaders().getFirst("Content-Type");
assertThat(contentType).isNotNull();
}
@@ -102,11 +96,11 @@ class RequestMappingIntegrationTests extends AbstractRequestMappingIntegrationTe
// One integration test to verify triggering of Forwarded header support.
// More fine-grained tests in ForwardedHeaderTransformerTests.
RequestEntity<Void> request = RequestEntity
.get(URI.create("http://localhost:" + this.port + "/uri"))
ResponseEntity<String> entity = getRestClient().get().uri("/uri")
.header("Forwarded", "host=84.198.58.199;proto=https")
.build();
ResponseEntity<String> entity = getRestTemplate().exchange(request, String.class);
.retrieve()
.toEntity(String.class);
assertThat(entity.getBody()).isEqualTo("https://84.198.58.199/uri");
}
@@ -366,7 +366,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
ResponseEntity<Void> entity = performPost("/person-create/publisher", JSON,
asList(new Person("Robert"), new Person("Marie")), null, Void.class);
asList(new Person("Robert"), new Person("Marie")), MediaType.ALL, Void.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -377,7 +377,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
People people = new People(new Person("Robert"), new Person("Marie"));
ResponseEntity<Void> response = performPost("/person-create/publisher", APPLICATION_XML, people, null, Void.class);
ResponseEntity<Void> response = performPost("/person-create/publisher", APPLICATION_XML, people, MediaType.ALL, Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -388,7 +388,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
ResponseEntity<Void> entity = performPost(
"/person-create/mono", JSON, new Person("Robert"), null, Void.class);
"/person-create/mono", JSON, new Person("Robert"), MediaType.ALL, Void.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(1);
@@ -399,7 +399,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
ResponseEntity<Void> entity = performPost(
"/person-create/single", JSON, new Person("Robert"), null, Void.class);
"/person-create/single", JSON, new Person("Robert"), MediaType.ALL, Void.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(1);
@@ -410,7 +410,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
ResponseEntity<Void> entity = performPost("/person-create/flux", JSON,
asList(new Person("Robert"), new Person("Marie")), null, Void.class);
asList(new Person("Robert"), new Person("Marie")), MediaType.ALL, Void.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -421,7 +421,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
People people = new People(new Person("Robert"), new Person("Marie"));
ResponseEntity<Void> response = performPost("/person-create/flux", APPLICATION_XML, people, null, Void.class);
ResponseEntity<Void> response = performPost("/person-create/flux", APPLICATION_XML, people, MediaType.ALL, Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -432,7 +432,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
ResponseEntity<Void> entity = performPost("/person-create/observable", JSON,
asList(new Person("Robert"), new Person("Marie")), null, Void.class);
asList(new Person("Robert"), new Person("Marie")), MediaType.ALL, Void.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -443,7 +443,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
People people = new People(new Person("Robert"), new Person("Marie"));
ResponseEntity<Void> response = performPost("/person-create/observable", APPLICATION_XML, people, null, Void.class);
ResponseEntity<Void> response = performPost("/person-create/observable", APPLICATION_XML, people, MediaType.ALL, Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -454,7 +454,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
ResponseEntity<Void> entity = performPost("/person-create/flowable", JSON,
asList(new Person("Robert"), new Person("Marie")), null, Void.class);
asList(new Person("Robert"), new Person("Marie")), MediaType.ALL, Void.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -465,7 +465,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
startServer(httpServer);
People people = new People(new Person("Robert"), new Person("Marie"));
ResponseEntity<Void> response = performPost("/person-create/flowable", APPLICATION_XML, people, null, Void.class);
ResponseEntity<Void> response = performPost("/person-create/flowable", APPLICATION_XML, people, MediaType.ALL, Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getApplicationContext().getBean(PersonCreateController.class).persons).hasSize(2);
@@ -474,7 +474,7 @@ class RequestMappingMessageConversionIntegrationTests extends AbstractRequestMap
@ParameterizedHttpServerTest // gh-23791
void personCreateViaDefaultMethodWithGenerics(HttpServer httpServer) throws Exception {
startServer(httpServer);
ResponseEntity<String> entity = performPost("/23791", JSON, new Person("Robert"), null, String.class);
ResponseEntity<String> entity = performPost("/23791", JSON, new Person("Robert"), MediaType.ALL, String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).isEqualTo("Person");
@@ -22,7 +22,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.accept.SemanticApiVersionParser.Version;
import org.springframework.web.bind.annotation.GetMapping;
@@ -77,18 +76,15 @@ class RequestMappingVersionIntegrationTests extends AbstractRequestMappingIntegr
@Test // gh-36059
void staticResourceWithInvalidApiVersion() throws Exception {
startServer(new TomcatHttpServer());
String url = "http://localhost:" + this.port + "/cp/test/foo.css";
RequestEntity<Void> requestEntity = RequestEntity.get(url).header("API-Version", "Invalid").build();
ResponseEntity<String> entity = getRestTemplate().exchange(requestEntity, String.class);
ResponseEntity<String> entity = getRestClient().get().uri("/cp/test/foo.css")
.header("API-Version", "Invalid").retrieve().toEntity(String.class);
assertThat(entity.getBody()).isEqualTo("h1 { color:red; }");
}
private ResponseEntity<String> exchangeWithVersion(String version) {
String url = "http://localhost:" + this.port;
RequestEntity<Void> requestEntity = RequestEntity.get(url).header("API-Version", version).build();
return getRestTemplate().exchange(requestEntity, String.class);
return getRestClient().get().uri("/").header("API-Version", version)
.retrieve().toEntity(String.class);
}
@@ -18,7 +18,6 @@ package org.springframework.web.reactive.result.method.annotation;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.util.Optional;
import org.springframework.context.ApplicationContext;
@@ -28,13 +27,12 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.ViewResolverRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@@ -69,9 +67,9 @@ class RequestMappingViewResolutionIntegrationTests extends AbstractRequestMappin
void etagCheckWithNotModifiedResponse(HttpServer httpServer) throws Exception {
startServer(httpServer);
URI uri = URI.create("http://localhost:" + this.port + "/html");
RequestEntity<Void> request = RequestEntity.get(uri).ifNoneMatch("\"deadb33f8badf00d\"").build();
ResponseEntity<String> response = getRestTemplate().exchange(request, String.class);
ResponseEntity<String> response = getRestClient().get().uri("/html")
.headers(headers -> headers.setIfNoneMatch("\"deadb33f8badf00d\""))
.retrieve().toEntity(String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_MODIFIED);
assertThat(response.getBody()).isNull();
@@ -89,9 +87,10 @@ class RequestMappingViewResolutionIntegrationTests extends AbstractRequestMappin
}
};
URI uri = URI.create("http://localhost:" + this.port + "/redirect");
RequestEntity<Void> request = RequestEntity.get(uri).accept(MediaType.ALL).build();
ResponseEntity<Void> response = new RestTemplate(factory).exchange(request, Void.class);
RestClient restClient = RestClient.builder().requestFactory(factory)
.baseUrl("http://localhost:" + this.port).build();
ResponseEntity<Void> response = restClient.get().uri("/redirect").accept(MediaType.ALL)
.retrieve().toEntity(Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SEE_OTHER);
assertThat(response.getHeaders().getLocation().toString()).isEqualTo("/");
@@ -76,7 +76,6 @@ class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
private void startServer(HttpServer httpServer, ClientHttpConnector connector) throws Exception {
super.startServer(httpServer);
this.webClient = WebClient
.builder()
.clientConnector(connector)
@@ -44,7 +44,6 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
@@ -59,7 +58,7 @@ import org.springframework.util.MimeTypeUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClient;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartResolver;
@@ -80,14 +79,13 @@ import static org.springframework.web.bind.annotation.RequestMethod.POST;
*/
class RequestPartIntegrationTests {
private RestTemplate restTemplate;
private static Server server;
private static String baseUrl;
private static Path tempDirectory;
private RestClient restClient;
@BeforeAll
static void startServer() throws Exception {
@@ -137,8 +135,10 @@ class RequestPartIntegrationTests {
MultipartHttpMessageConverter converter = new MultipartHttpMessageConverter(converters);
restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
restTemplate.setMessageConverters(Collections.singletonList(converter));
this.restClient = RestClient.builder().baseUrl(baseUrl)
.requestFactory(new HttpComponentsClientHttpRequestFactory())
.configureMessageConverters(clientBuilder -> clientBuilder.addCustomConverter(converter))
.build();
}
@@ -162,16 +162,19 @@ class RequestPartIntegrationTests {
"content\r\n" +
"--" + boundaryText + "--\r\n ";
RequestEntity<byte[]> requestEntity =
RequestEntity.post(URI.create(baseUrl + "/standard-resolver/spr13319"))
.contentType(new MediaType(MediaType.MULTIPART_FORM_DATA, params))
.body(content.getBytes(StandardCharsets.US_ASCII));
ByteArrayHttpMessageConverter byteArrayConverter = new ByteArrayHttpMessageConverter();
byteArrayConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.MULTIPART_FORM_DATA));
this.restClient = RestClient.builder().baseUrl(baseUrl)
.requestFactory(new HttpComponentsClientHttpRequestFactory())
.configureMessageConverters(clientBuilder -> clientBuilder.addCustomConverter(byteArrayConverter))
.build();
ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.MULTIPART_FORM_DATA));
this.restTemplate.setMessageConverters(Collections.singletonList(converter));
ResponseEntity<Void> responseEntity = this.restClient.post().uri("/standard-resolver/spr13319")
.contentType(new MediaType(MediaType.MULTIPART_FORM_DATA, params))
.body(content.getBytes(StandardCharsets.US_ASCII))
.retrieve()
.toBodilessEntity();
ResponseEntity<Void> responseEntity = restTemplate.exchange(requestEntity, Void.class);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -185,8 +188,9 @@ class RequestPartIntegrationTests {
headers.setContentType(new MediaType("application", "octet-stream", StandardCharsets.ISO_8859_1));
parts.add("iso-8859-1-data", new HttpEntity<>(new byte[] {(byte) 0xC4}, headers)); // SPR-13096
URI location = restTemplate.postForLocation(url, parts);
assertThat(location.toString()).isEqualTo(("http://localhost:8080/test/" + basename + "/logo.jpg"));
ResponseEntity<Void> response = this.restClient.post().uri(url).contentType(MediaType.MULTIPART_FORM_DATA)
.body(parts).retrieve().toBodilessEntity();
assertThat(response.getHeaders().getLocation().toString()).isEqualTo(("http://localhost:8080/test/" + basename + "/logo.jpg"));
}