Polish "simple" handler support
- correct name of HttpHandlerHandlerAdapter to WebHandlerHandlerAdapter - shorten SimpleHandlerResultHandler to SimpleResultHandler - add HandlerResult constructor without Model - update tests
This commit is contained in:
parent
ff6b639cf9
commit
3460e577ad
|
@ -44,6 +44,16 @@ public class HandlerResult {
|
|||
private Function<Throwable, Mono<HandlerResult>> exceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code HandlerResult}.
|
||||
* @param handler the handler that handled the request
|
||||
* @param returnValue the return value from the handler possibly {@code null}
|
||||
* @param returnValueType the return value type
|
||||
*/
|
||||
public HandlerResult(Object handler, Object returnValue, ResolvableType returnValueType) {
|
||||
this(handler, returnValue, returnValueType, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code HandlerResult}.
|
||||
* @param handler the handler that handled the request
|
||||
|
@ -54,11 +64,10 @@ public class HandlerResult {
|
|||
public HandlerResult(Object handler, Object returnValue, ResolvableType returnValueType, ModelMap model) {
|
||||
Assert.notNull(handler, "'handler' is required");
|
||||
Assert.notNull(returnValueType, "'returnValueType' is required");
|
||||
Assert.notNull(model, "'model' is required");
|
||||
this.handler = handler;
|
||||
this.returnValue = Optional.ofNullable(returnValue);
|
||||
this.returnValueType = returnValueType;
|
||||
this.model = model;
|
||||
this.model = (model != null ? model : new ExtendedModelMap());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -29,24 +29,28 @@ import org.springframework.web.reactive.HandlerResult;
|
|||
import org.springframework.web.reactive.HandlerResultHandler;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
|
||||
/**
|
||||
* Supports {@link HandlerResult} with a {@code void} or {@code Publisher<Void>} value.
|
||||
* An optional {link ConversionService} can be used to support types that can be converted to
|
||||
* {@code Publisher<Void>}, like {@code Observable<Void>} or {@code CompletableFuture<Void>}.
|
||||
* A simple handler for return values of type {@code void}, or
|
||||
* {@code Publisher<Void>}, or if a {link ConversionService} is provided, also
|
||||
* of any other async return value types that can be converted to
|
||||
* {@code Publisher<Void>} such as {@code Observable<Void>} or
|
||||
* {@code CompletableFuture<Void>}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class SimpleHandlerResultHandler implements Ordered, HandlerResultHandler {
|
||||
public class SimpleResultHandler implements Ordered, HandlerResultHandler {
|
||||
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
|
||||
public SimpleHandlerResultHandler() {
|
||||
public SimpleResultHandler() {
|
||||
}
|
||||
|
||||
public SimpleHandlerResultHandler(ConversionService conversionService) {
|
||||
public SimpleResultHandler(ConversionService conversionService) {
|
||||
Assert.notNull(conversionService, "'conversionService' is required.");
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
@ -61,30 +65,36 @@ public class SimpleHandlerResultHandler implements Ordered, HandlerResultHandler
|
|||
return this.order;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supports(HandlerResult result) {
|
||||
ResolvableType type = result.getReturnValueType();
|
||||
return (type != null && Void.TYPE.equals(type.getRawClass()) ||
|
||||
(isConvertibleToPublisher(type) && Void.class.isAssignableFrom(type.getGeneric(0).getRawClass())));
|
||||
return (type != null && (Void.TYPE.equals(type.getRawClass()) || isConvertibleToVoidPublisher(type)));
|
||||
}
|
||||
|
||||
private boolean isConvertibleToVoidPublisher(ResolvableType type) {
|
||||
return (isConvertibleToPublisher(type) &&
|
||||
Void.class.isAssignableFrom(type.getGeneric(0).getRawClass()));
|
||||
}
|
||||
|
||||
private boolean isConvertibleToPublisher(ResolvableType type) {
|
||||
return Publisher.class.isAssignableFrom(type.getRawClass()) ||
|
||||
((this.conversionService != null) &&
|
||||
this.conversionService.canConvert(type.getRawClass(), Publisher.class));
|
||||
Class<?> clazz = type.getRawClass();
|
||||
return (Publisher.class.isAssignableFrom(clazz) ||
|
||||
((this.conversionService != null) && this.conversionService.canConvert(clazz, Publisher.class)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
|
||||
Optional<Object> value = result.getReturnValue();
|
||||
if (!value.isPresent() || Void.TYPE.equals(result.getReturnValueType().getRawClass())) {
|
||||
Optional<Object> optional = result.getReturnValue();
|
||||
if (!optional.isPresent()) {
|
||||
return Mono.empty();
|
||||
}
|
||||
if (value.get() instanceof Mono) {
|
||||
return (Mono<Void>) value.get();
|
||||
Object returnValue = optional.get();
|
||||
if (returnValue instanceof Mono) {
|
||||
return (Mono<Void>) returnValue;
|
||||
}
|
||||
return Mono.from(this.conversionService.convert(value.get(), Publisher.class));
|
||||
return Mono.from(this.conversionService.convert(returnValue, Publisher.class));
|
||||
}
|
||||
|
||||
}
|
|
@ -29,13 +29,12 @@ import org.springframework.web.server.WebHandler;
|
|||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Support use of {@link org.springframework.web.server.WebHandler} through the
|
||||
* {@link DispatcherHandler}.
|
||||
* Adapter to use a {@link WebHandler} through the {@link DispatcherHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class HttpHandlerHandlerAdapter implements HandlerAdapter {
|
||||
public class WebHandlerHandlerAdapter implements HandlerAdapter {
|
||||
|
||||
private static final ResolvableType PUBLISHER_VOID = ResolvableType.forClassWithGenerics(
|
||||
Publisher.class, Void.class);
|
||||
|
@ -49,9 +48,8 @@ public class HttpHandlerHandlerAdapter implements HandlerAdapter {
|
|||
@Override
|
||||
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
|
||||
WebHandler webHandler = (WebHandler) handler;
|
||||
Mono<Void> completion = webHandler.handle(exchange);
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
return Mono.just(new HandlerResult(webHandler, completion, PUBLISHER_VOID, model));
|
||||
Mono<Void> mono = webHandler.handle(exchange);
|
||||
return Mono.just(new HandlerResult(webHandler, mono, PUBLISHER_VOID));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -27,7 +27,6 @@ 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.ReactiveStreamsToRxJava1Converter;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
|
||||
|
@ -37,12 +36,12 @@ import static org.junit.Assert.assertTrue;
|
|||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class SimpleHandlerResultHandlerTests {
|
||||
public class SimpleResultHandlerTests {
|
||||
|
||||
@Test
|
||||
public void supports() throws NoSuchMethodException {
|
||||
|
||||
SimpleHandlerResultHandler resultHandler = new SimpleHandlerResultHandler();
|
||||
SimpleResultHandler resultHandler = new SimpleResultHandler();
|
||||
TestController controller = new TestController();
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller, TestController.class.getMethod("voidReturnValue"));
|
||||
|
@ -77,7 +76,7 @@ public class SimpleHandlerResultHandlerTests {
|
|||
GenericConversionService conversionService = new GenericConversionService();
|
||||
conversionService.addConverter(new ReactiveStreamsToCompletableFutureConverter());
|
||||
conversionService.addConverter(new ReactiveStreamsToRxJava1Converter());
|
||||
SimpleHandlerResultHandler resultHandler = new SimpleHandlerResultHandler(conversionService);
|
||||
SimpleResultHandler resultHandler = new SimpleResultHandler(conversionService);
|
||||
TestController controller = new TestController();
|
||||
|
||||
HandlerMethod hm = new HandlerMethod(controller, TestController.class.getMethod("voidReturnValue"));
|
||||
|
@ -106,7 +105,7 @@ public class SimpleHandlerResultHandlerTests {
|
|||
}
|
||||
|
||||
private HandlerResult createHandlerResult(HandlerMethod hm, ResolvableType type) {
|
||||
return new HandlerResult(hm, null, type, new ExtendedModelMap());
|
||||
return new HandlerResult(hm, null, type);
|
||||
}
|
||||
|
||||
|
|
@ -47,9 +47,11 @@ import static org.junit.Assert.assertEquals;
|
|||
|
||||
|
||||
/**
|
||||
* Integration tests with simple WebHandler's processing requests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
public class WebHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
|
||||
|
@ -59,14 +61,14 @@ public class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandler
|
|||
|
||||
StaticApplicationContext wac = new StaticApplicationContext();
|
||||
wac.registerSingleton("hm", TestHandlerMapping.class);
|
||||
wac.registerSingleton("ha", HttpHandlerHandlerAdapter.class);
|
||||
wac.registerSingleton("rh", SimpleHandlerResultHandler.class);
|
||||
wac.registerSingleton("ha", WebHandlerHandlerAdapter.class);
|
||||
wac.registerSingleton("rh", SimpleResultHandler.class);
|
||||
wac.refresh();
|
||||
|
||||
DispatcherHandler webHandler = new DispatcherHandler();
|
||||
webHandler.setApplicationContext(wac);
|
||||
DispatcherHandler dispatcherHandler = new DispatcherHandler();
|
||||
dispatcherHandler.setApplicationContext(wac);
|
||||
|
||||
return WebHttpHandlerBuilder.webHandler(webHandler)
|
||||
return WebHttpHandlerBuilder.webHandler(dispatcherHandler)
|
||||
.exceptionHandlers(new ResponseStatusExceptionHandler())
|
||||
.build();
|
||||
}
|
||||
|
@ -137,12 +139,16 @@ public class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandler
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static DataBuffer asDataBuffer(String text) {
|
||||
return new DefaultDataBufferAllocator().allocateBuffer().write(text.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private static class FooHandler implements WebHandler {
|
||||
|
||||
@Override
|
||||
public Mono<Void> handle(ServerWebExchange exchange) {
|
||||
DataBuffer buffer = new DefaultDataBufferAllocator().allocateBuffer()
|
||||
.write("foo".getBytes(StandardCharsets.UTF_8));
|
||||
DataBuffer buffer = asDataBuffer("foo");
|
||||
return exchange.getResponse().setBody(Flux.just(buffer));
|
||||
}
|
||||
}
|
||||
|
@ -151,8 +157,7 @@ public class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandler
|
|||
|
||||
@Override
|
||||
public Mono<Void> handle(ServerWebExchange exchange) {
|
||||
DataBuffer buffer = new DefaultDataBufferAllocator().allocateBuffer()
|
||||
.write("bar".getBytes(StandardCharsets.UTF_8));
|
||||
DataBuffer buffer = asDataBuffer("bar");
|
||||
return exchange.getResponse().setBody(Flux.just(buffer));
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.DispatcherHandler;
|
||||
import org.springframework.web.reactive.ViewResolver;
|
||||
import org.springframework.web.reactive.handler.SimpleHandlerResultHandler;
|
||||
import org.springframework.web.reactive.handler.SimpleResultHandler;
|
||||
import org.springframework.web.reactive.view.ViewResolverResultHandler;
|
||||
import org.springframework.web.reactive.view.freemarker.FreeMarkerConfigurer;
|
||||
import org.springframework.web.reactive.view.freemarker.FreeMarkerViewResolver;
|
||||
|
@ -421,8 +421,8 @@ public class RequestMappingIntegrationTests extends AbstractHttpHandlerIntegrati
|
|||
}
|
||||
|
||||
@Bean
|
||||
public SimpleHandlerResultHandler simpleHandlerResultHandler() {
|
||||
SimpleHandlerResultHandler resultHandler = new SimpleHandlerResultHandler(conversionService());
|
||||
public SimpleResultHandler simpleHandlerResultHandler() {
|
||||
SimpleResultHandler resultHandler = new SimpleResultHandler(conversionService());
|
||||
resultHandler.setOrder(2);
|
||||
return resultHandler;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue