HandlerMapping is now asynchronous
This commit is contained in:
parent
dc57e2621c
commit
d319edba28
|
@ -98,41 +98,33 @@ public class DispatcherHandler implements ReactiveHttpHandler, ApplicationContex
|
|||
logger.debug("Processing " + request.getMethod() + " request for [" + request.getURI() + "]");
|
||||
}
|
||||
|
||||
Object handler = getHandler(request);
|
||||
if (handler == null) {
|
||||
Publisher<Object> handlerPublisher = getHandler(request);
|
||||
if (handlerPublisher == null) {
|
||||
// No exception handling mechanism yet
|
||||
response.setStatusCode(HttpStatus.NOT_FOUND);
|
||||
response.writeHeaders();
|
||||
return Publishers.empty();
|
||||
}
|
||||
|
||||
HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
|
||||
if (handlerAdapter == null) {
|
||||
return Publishers.error(new IllegalStateException("No HandlerAdapter for " + handler));
|
||||
}
|
||||
|
||||
Publisher<HandlerResult> resultPublisher = handlerAdapter.handle(request, response, handler);
|
||||
Publisher<HandlerResult> resultPublisher = Publishers.concatMap(handlerPublisher, handler -> {
|
||||
HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
|
||||
return handlerAdapter.handle(request, response, handler);
|
||||
});
|
||||
|
||||
return Publishers.concatMap(resultPublisher, result -> {
|
||||
for (HandlerResultHandler resultHandler : resultHandlers) {
|
||||
if (resultHandler.supports(result)) {
|
||||
return resultHandler.handleResult(request, response, result);
|
||||
}
|
||||
}
|
||||
return Publishers.error(new IllegalStateException(
|
||||
"No HandlerResultHandler for " + result.getValue()));
|
||||
HandlerResultHandler handler = getResultHandler(result);
|
||||
return handler.handleResult(request, response, result);
|
||||
});
|
||||
}
|
||||
|
||||
protected Object getHandler(ReactiveServerHttpRequest request) {
|
||||
Object handler = null;
|
||||
protected Publisher<Object> getHandler(ReactiveServerHttpRequest request) {
|
||||
for (HandlerMapping handlerMapping : this.handlerMappings) {
|
||||
handler = handlerMapping.getHandler(request);
|
||||
if (handler != null) {
|
||||
break;
|
||||
Publisher<Object> handlerPublisher = handlerMapping.getHandler(request);
|
||||
if (handlerPublisher != null) {
|
||||
return handlerPublisher;
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected HandlerAdapter getHandlerAdapter(Object handler) {
|
||||
|
@ -141,7 +133,16 @@ public class DispatcherHandler implements ReactiveHttpHandler, ApplicationContex
|
|||
return handlerAdapter;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalStateException("No HandlerAdapter: " + handler);
|
||||
}
|
||||
|
||||
protected HandlerResultHandler getResultHandler(HandlerResult handlerResult) {
|
||||
for (HandlerResultHandler resultHandler : resultHandlers) {
|
||||
if (resultHandler.supports(handlerResult)) {
|
||||
return resultHandler;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No HandlerResultHandler: " + handlerResult.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.reactive;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.http.server.ReactiveServerHttpRequest;
|
||||
|
||||
/**
|
||||
|
@ -23,6 +25,6 @@ import org.springframework.http.server.ReactiveServerHttpRequest;
|
|||
*/
|
||||
public interface HandlerMapping {
|
||||
|
||||
Object getHandler(ReactiveServerHttpRequest request);
|
||||
Publisher<Object> getHandler(ReactiveServerHttpRequest request);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ package org.springframework.web.reactive.handler;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.Publishers;
|
||||
|
||||
import org.springframework.http.server.ReactiveServerHttpRequest;
|
||||
import org.springframework.web.reactive.HandlerMapping;
|
||||
|
||||
|
@ -39,8 +42,10 @@ public class SimpleUrlHandlerMapping implements HandlerMapping {
|
|||
|
||||
|
||||
@Override
|
||||
public Object getHandler(ReactiveServerHttpRequest request) {
|
||||
return this.handlerMap.get(request.getURI().getPath());
|
||||
public Publisher<Object> getHandler(ReactiveServerHttpRequest request) {
|
||||
String path = request.getURI().getPath();
|
||||
Object handler = this.handlerMap.get(path);
|
||||
return (handler != null ? Publishers.just(handler) : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import java.util.TreeSet;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.Publishers;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
@ -92,15 +94,16 @@ public class RequestMappingHandlerMapping implements HandlerMapping,
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object getHandler(ReactiveServerHttpRequest request) {
|
||||
public Publisher<Object> getHandler(ReactiveServerHttpRequest request) {
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : this.methodMap.entrySet()) {
|
||||
RequestMappingInfo info = entry.getKey();
|
||||
if (info.matchesRequest(request)) {
|
||||
HandlerMethod handlerMethod = entry.getValue();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Mapped " + request.getMethod() + " " +
|
||||
request.getURI().getPath() + " to [" + entry.getValue() + "]");
|
||||
request.getURI().getPath() + " to [" + handlerMethod + "]");
|
||||
}
|
||||
return entry.getValue();
|
||||
return Publishers.just(handlerMethod);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -19,10 +19,13 @@ package org.springframework.web.reactive.method.annotation;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.rx.Streams;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
@ -34,6 +37,7 @@ import org.springframework.web.context.support.StaticWebApplicationContext;
|
|||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
|
@ -56,19 +60,29 @@ public class RequestMappingHandlerMappingTests {
|
|||
@Test
|
||||
public void path() throws Exception {
|
||||
ReactiveServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, "boo");
|
||||
HandlerMethod handler = (HandlerMethod) this.mapping.getHandler(request);
|
||||
assertEquals(TestController.class.getMethod("boo"), handler.getMethod());
|
||||
Publisher<?> handlerPublisher = this.mapping.getHandler(request);
|
||||
HandlerMethod handlerMethod = toHandlerMethod(handlerPublisher);
|
||||
assertEquals(TestController.class.getMethod("boo"), handlerMethod.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void method() throws Exception {
|
||||
ReactiveServerHttpRequest request = new MockServerHttpRequest(HttpMethod.POST, "foo");
|
||||
HandlerMethod handler = (HandlerMethod) this.mapping.getHandler(request);
|
||||
assertEquals(TestController.class.getMethod("postFoo"), handler.getMethod());
|
||||
Publisher<?> handlerPublisher = this.mapping.getHandler(request);
|
||||
HandlerMethod handlerMethod = toHandlerMethod(handlerPublisher);
|
||||
assertEquals(TestController.class.getMethod("postFoo"), handlerMethod.getMethod());
|
||||
|
||||
request = new MockServerHttpRequest(HttpMethod.GET, "foo");
|
||||
handler = (HandlerMethod) this.mapping.getHandler(request);
|
||||
assertEquals(TestController.class.getMethod("getFoo"), handler.getMethod());
|
||||
handlerPublisher = this.mapping.getHandler(request);
|
||||
handlerMethod = toHandlerMethod(handlerPublisher);
|
||||
assertEquals(TestController.class.getMethod("getFoo"), handlerMethod.getMethod());
|
||||
}
|
||||
|
||||
private HandlerMethod toHandlerMethod(Publisher<?> handlerPublisher) throws InterruptedException {
|
||||
assertNotNull(handlerPublisher);
|
||||
List<?> handlerList = Streams.wrap(handlerPublisher).toList().await(5, TimeUnit.SECONDS);
|
||||
assertEquals(1, handlerList.size());
|
||||
return (HandlerMethod) handlerList.get(0);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue