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:
Rossen Stoyanchev
2016-04-14 14:50:59 -04:00
parent ff6b639cf9
commit 3460e577ad
6 changed files with 65 additions and 44 deletions

View File

@@ -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());
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}