Support handler methods returning void, Observable<Void>, etc.
This commit is contained in:
@@ -16,12 +16,20 @@
|
||||
|
||||
package org.springframework.web.reactive.handler;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.rx.Stream;
|
||||
import rx.Observable;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.convert.support.ReactiveStreamsToCompletableFutureConverter;
|
||||
import org.springframework.core.convert.support.ReactiveStreamsToReactorConverter;
|
||||
import org.springframework.core.convert.support.ReactiveStreamsToRxJava1Converter;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
|
||||
@@ -38,7 +46,7 @@ public class SimpleHandlerResultHandlerTests {
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller, TestController.class.getMethod("voidReturnValue"));
|
||||
ResolvableType type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherString"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
@@ -47,14 +55,61 @@ public class SimpleHandlerResultHandlerTests {
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("streamVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
// Reactor Stream is a Publisher
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("observableVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("completableFutureVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsWithConversionService() throws NoSuchMethodException {
|
||||
|
||||
GenericConversionService conversionService = new GenericConversionService();
|
||||
conversionService.addConverter(new ReactiveStreamsToCompletableFutureConverter());
|
||||
conversionService.addConverter(new ReactiveStreamsToReactorConverter());
|
||||
conversionService.addConverter(new ReactiveStreamsToRxJava1Converter());
|
||||
SimpleHandlerResultHandler resultHandler = new SimpleHandlerResultHandler(conversionService);
|
||||
TestController controller = new TestController();
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller, TestController.class.getMethod("voidReturnValue"));
|
||||
ResolvableType type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherString"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertFalse(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("publisherVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("streamVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("observableVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
|
||||
hm = new HandlerMethod(controller, TestController.class.getMethod("completableFutureVoid"));
|
||||
type = ResolvableType.forMethodParameter(hm.getReturnType());
|
||||
assertTrue(resultHandler.supports(new HandlerResult(hm, null, type)));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class TestController {
|
||||
|
||||
public Publisher<String> voidReturnValue() {
|
||||
return null;
|
||||
public void voidReturnValue() {
|
||||
}
|
||||
|
||||
public Publisher<String> publisherString() {
|
||||
@@ -64,6 +119,18 @@ public class SimpleHandlerResultHandlerTests {
|
||||
public Publisher<Void> publisherVoid() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Stream<Void> streamVoid() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Observable<Void> observableVoid() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> completableFutureVoid() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -197,16 +197,18 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create() throws Exception {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
URI url = new URI("http://localhost:" + this.port + "/create");
|
||||
RequestEntity<List<Person>> request = RequestEntity.post(url)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(Arrays.asList(new Person("Robert"), new Person("Marie")));
|
||||
ResponseEntity<Void> response = restTemplate.exchange(request, Void.class);
|
||||
public void publisherCreate() throws Exception {
|
||||
create("http://localhost:" + this.port + "/publisher-create");
|
||||
}
|
||||
|
||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||
assertEquals(2, this.wac.getBean(TestController.class).persons.size());
|
||||
@Test
|
||||
public void streamCreate() throws Exception {
|
||||
create("http://localhost:" + this.port + "/stream-create");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void observableCreate() throws Exception {
|
||||
create("http://localhost:" + this.port + "/observable-create");
|
||||
}
|
||||
|
||||
|
||||
@@ -259,6 +261,18 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati
|
||||
assertEquals("MARIE", results.get(1).getName());
|
||||
}
|
||||
|
||||
private void create(String requestUrl) throws Exception {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
URI url = new URI(requestUrl);
|
||||
RequestEntity<List<Person>> request = RequestEntity.post(url)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(Arrays.asList(new Person("Robert"), new Person("Marie")));
|
||||
ResponseEntity<Void> response = restTemplate.exchange(request, Void.class);
|
||||
|
||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||
assertEquals(2, this.wac.getBean(TestController.class).persons.size());
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
@@ -295,7 +309,7 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati
|
||||
|
||||
@Bean
|
||||
public SimpleHandlerResultHandler simpleHandlerResultHandler() {
|
||||
return new SimpleHandlerResultHandler();
|
||||
return new SimpleHandlerResultHandler(conversionService());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -448,11 +462,21 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati
|
||||
});
|
||||
}
|
||||
|
||||
@RequestMapping("/create")
|
||||
public Publisher<Void> create(@RequestBody Stream<Person> personStream) {
|
||||
@RequestMapping("/publisher-create")
|
||||
public Publisher<Void> publisherCreate(@RequestBody Publisher<Person> personStream) {
|
||||
return Streams.wrap(personStream).toList().onSuccess(persons::addAll).after();
|
||||
}
|
||||
|
||||
@RequestMapping("/stream-create")
|
||||
public Promise<Void> streamCreate(@RequestBody Stream<Person> personStream) {
|
||||
return personStream.toList().onSuccess(persons::addAll).after();
|
||||
}
|
||||
|
||||
@RequestMapping("/observable-create")
|
||||
public Observable<Void> observableCreate(@RequestBody Observable<Person> personStream) {
|
||||
return personStream.toList().doOnNext(p -> persons.addAll(p)).flatMap(document -> Observable.empty());
|
||||
}
|
||||
|
||||
//TODO add mixed and T request mappings tests
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user