Use ParameterizedTypeReference in public-facing WebFlux APIs
This commit changes the use of `ResolvableType` to `ParameterizedTypeReference` in all public-facing WebFlux APIs. This change removes the necessity for providing the parameterized type information twice: once for creating the `ResolvableType`, and once for specifying a `BodyExtractor`. Issue: SPR-15636
This commit is contained in:
@@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -32,6 +33,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
@@ -120,6 +122,28 @@ public class BodyExtractorsTests {
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMonoParameterizedTypeReference() throws Exception {
|
||||
ParameterizedTypeReference<Map<String, String>> typeReference = new ParameterizedTypeReference<Map<String, String>>() {};
|
||||
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(typeReference);
|
||||
|
||||
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
|
||||
DefaultDataBuffer dataBuffer =
|
||||
factory.wrap(ByteBuffer.wrap("{\"username\":\"foo\",\"password\":\"bar\"}".getBytes(StandardCharsets.UTF_8)));
|
||||
Flux<DataBuffer> body = Flux.just(dataBuffer);
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.post("/").contentType(MediaType.APPLICATION_JSON).body(body);
|
||||
Mono<Map<String, String>> result = extractor.extract(request, this.context);
|
||||
|
||||
Map<String, String > expected = new LinkedHashMap<>();
|
||||
expected.put("username", "foo");
|
||||
expected.put("password", "bar");
|
||||
StepVerifier.create(result)
|
||||
.expectNext(expected)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMonoWithHints() throws Exception {
|
||||
BodyExtractor<Mono<User>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(User.class);
|
||||
|
||||
@@ -30,7 +30,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.codec.CharSequenceEncoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
@@ -70,10 +70,10 @@ public class DefaultEntityResponseBuilderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromPublisherResolvableType() throws Exception {
|
||||
public void fromPublisher() throws Exception {
|
||||
Flux<String> body = Flux.just("foo", "bar");
|
||||
ResolvableType type = ResolvableType.forClass(String.class);
|
||||
EntityResponse<Flux<String>> response = EntityResponse.fromPublisher(body, type).build().block();
|
||||
ParameterizedTypeReference<String> typeReference = new ParameterizedTypeReference<String>() {};
|
||||
EntityResponse<Flux<String>> response = EntityResponse.fromPublisher(body, typeReference).build().block();
|
||||
assertSame(body, response.entity());
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,15 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.codec.ServerSentEvent;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.core.ResolvableType.*;
|
||||
import static org.springframework.http.MediaType.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
|
||||
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromServerSentEvents;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
@@ -94,7 +94,7 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
||||
.accept(TEXT_EVENT_STREAM)
|
||||
.exchange()
|
||||
.flatMapMany(response -> response.body(toFlux(
|
||||
forClassWithGenerics(ServerSentEvent.class, String.class))));
|
||||
new ParameterizedTypeReference<ServerSentEvent<String>>() {})));
|
||||
|
||||
StepVerifier.create(result)
|
||||
.consumeNextWith( event -> {
|
||||
|
||||
@@ -26,6 +26,7 @@ import reactor.test.StepVerifier;
|
||||
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.core.ResolvableType;
|
||||
import org.springframework.http.codec.ServerSentEvent;
|
||||
import org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests;
|
||||
@@ -38,9 +39,9 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.core.ResolvableType.*;
|
||||
import static org.springframework.http.MediaType.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
@@ -106,7 +107,7 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
.uri("/event")
|
||||
.accept(TEXT_EVENT_STREAM)
|
||||
.exchange()
|
||||
.flatMapMany(response -> response.body(toFlux(type)));
|
||||
.flatMapMany(response -> response.body(toFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {})));
|
||||
|
||||
StepVerifier.create(result)
|
||||
.consumeNextWith( event -> {
|
||||
@@ -133,8 +134,7 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
.uri("/event")
|
||||
.accept(TEXT_EVENT_STREAM)
|
||||
.exchange()
|
||||
.flatMapMany(response -> response.body(toFlux(
|
||||
forClassWithGenerics(ServerSentEvent.class, String.class))));
|
||||
.flatMapMany(response -> response.body(toFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {})));
|
||||
|
||||
StepVerifier.create(result)
|
||||
.consumeNextWith( event -> {
|
||||
|
||||
Reference in New Issue
Block a user