Add support for WebFilter and WebExceptionHandler

This commit adds support for configuring `WebFilter` and
`WebExceptionHandler` instances in HandlerStrategies. It also drops the
"native" support for `ResponseStatusException`s, in favor of the
`ResponseStatusExceptionHandler`, which is registered by default.

Issue: SPR-15518
This commit is contained in:
Arjen Poutsma
2017-05-10 14:35:32 +02:00
parent ad9cf99420
commit f4cf55cb2b
7 changed files with 138 additions and 54 deletions

View File

@@ -26,7 +26,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.junit.Before;
import org.junit.Test;
@@ -52,9 +53,8 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
import org.springframework.web.server.WebSession;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
/**
@@ -64,11 +64,9 @@ public class DefaultServerRequestTests {
private ServerHttpRequest mockRequest;
private ServerHttpResponse mockResponse;
private ServerWebExchange mockExchange;
private HandlerStrategies mockHandlerStrategies;
Supplier<Stream<HttpMessageReader<?>>> messageReaders;
private DefaultServerRequest defaultRequest;
@@ -76,14 +74,15 @@ public class DefaultServerRequestTests {
@Before
public void createMocks() {
mockRequest = mock(ServerHttpRequest.class);
mockResponse = mock(ServerHttpResponse.class);
ServerHttpResponse mockResponse = mock(ServerHttpResponse.class);
mockExchange = mock(ServerWebExchange.class);
when(mockExchange.getRequest()).thenReturn(mockRequest);
when(mockExchange.getResponse()).thenReturn(mockResponse);
mockHandlerStrategies = mock(HandlerStrategies.class);
defaultRequest = new DefaultServerRequest(mockExchange, mockHandlerStrategies);
this.messageReaders = Collections.<HttpMessageReader<?>>singleton(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)))::stream;
defaultRequest = new DefaultServerRequest(mockExchange, messageReaders);
}
@@ -190,10 +189,6 @@ public class DefaultServerRequestTests {
when(mockRequest.getHeaders()).thenReturn(httpHeaders);
when(mockRequest.getBody()).thenReturn(body);
Set<HttpMessageReader<?>> messageReaders = Collections
.singleton(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
when(mockHandlerStrategies.messageReaders()).thenReturn(messageReaders::stream);
Mono<String> resultMono = defaultRequest.body(toMono(String.class));
assertEquals("foo", resultMono.block());
}
@@ -210,10 +205,6 @@ public class DefaultServerRequestTests {
when(mockRequest.getHeaders()).thenReturn(httpHeaders);
when(mockRequest.getBody()).thenReturn(body);
Set<HttpMessageReader<?>> messageReaders = Collections
.singleton(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
when(mockHandlerStrategies.messageReaders()).thenReturn(messageReaders::stream);
Mono<String> resultMono = defaultRequest.bodyToMono(String.class);
assertEquals("foo", resultMono.block());
}
@@ -230,10 +221,6 @@ public class DefaultServerRequestTests {
when(mockRequest.getHeaders()).thenReturn(httpHeaders);
when(mockRequest.getBody()).thenReturn(body);
Set<HttpMessageReader<?>> messageReaders = Collections
.singleton(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
when(mockHandlerStrategies.messageReaders()).thenReturn(messageReaders::stream);
Flux<String> resultFlux = defaultRequest.bodyToFlux(String.class);
Mono<List<String>> result = resultFlux.collectList();
assertEquals(Collections.singletonList("foo"), result.block());
@@ -251,8 +238,8 @@ public class DefaultServerRequestTests {
when(mockRequest.getHeaders()).thenReturn(httpHeaders);
when(mockRequest.getBody()).thenReturn(body);
Set<HttpMessageReader<?>> messageReaders = Collections.emptySet();
when(mockHandlerStrategies.messageReaders()).thenReturn(messageReaders::stream);
this.messageReaders = Collections.<HttpMessageReader<?>>emptySet()::stream;
this.defaultRequest = new DefaultServerRequest(mockExchange, messageReaders);
Flux<String> resultFlux = defaultRequest.bodyToFlux(String.class);
StepVerifier.create(resultFlux)

View File

@@ -33,8 +33,7 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.mock.http.server.reactive.test.MockServerWebExchange;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
/**
* @author Arjen Poutsma
@@ -51,7 +50,7 @@ public class ResourceHandlerFunctionTests {
MockServerWebExchange exchange = MockServerHttpRequest.get("http://localhost").toExchange();
MockServerHttpResponse mockResponse = exchange.getResponse();
ServerRequest request = new DefaultServerRequest(exchange, HandlerStrategies.withDefaults());
ServerRequest request = new DefaultServerRequest(exchange, HandlerStrategies.withDefaults().messageReaders());
Mono<ServerResponse> responseMono = this.handlerFunction.handle(request);
@@ -86,7 +85,7 @@ public class ResourceHandlerFunctionTests {
MockServerWebExchange exchange = MockServerHttpRequest.head("http://localhost").toExchange();
MockServerHttpResponse mockResponse = exchange.getResponse();
ServerRequest request = new DefaultServerRequest(exchange, HandlerStrategies.withDefaults());
ServerRequest request = new DefaultServerRequest(exchange, HandlerStrategies.withDefaults().messageReaders());
Mono<ServerResponse> responseMono = this.handlerFunction.handle(request);
@@ -110,7 +109,7 @@ public class ResourceHandlerFunctionTests {
MockServerWebExchange exchange = MockServerHttpRequest.options("http://localhost").toExchange();
MockServerHttpResponse mockResponse = exchange.getResponse();
ServerRequest request = new DefaultServerRequest(exchange, HandlerStrategies.withDefaults());
ServerRequest request = new DefaultServerRequest(exchange, HandlerStrategies.withDefaults().messageReaders());
Mono<ServerResponse> responseMono = this.handlerFunction.handle(request);
Mono<Void> result = responseMono.flatMap(response -> {

View File

@@ -17,6 +17,7 @@
package org.springframework.web.reactive.function.server;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import reactor.core.publisher.Mono;
@@ -29,6 +30,8 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@@ -245,4 +248,35 @@ public class RouterFunctionsTests {
assertEquals(HttpStatus.NOT_FOUND, httpResponse.getStatusCode());
}
@Test
public void toHttpHandlerWebFilter() throws Exception {
AtomicBoolean filterInvoked = new AtomicBoolean();
WebFilter webFilter = new WebFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
filterInvoked.set(true);
return chain.filter(exchange);
}
};
HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.accepted().build();
RouterFunction<ServerResponse> routerFunction =
RouterFunctions.route(RequestPredicates.all(), handlerFunction);
HandlerStrategies handlerStrategies = HandlerStrategies.builder()
.webFilter(webFilter).build();
HttpHandler result = RouterFunctions.toHttpHandler(routerFunction, handlerStrategies);
assertNotNull(result);
MockServerHttpRequest httpRequest = MockServerHttpRequest.get("http://localhost").build();
MockServerHttpResponse httpResponse = new MockServerHttpResponse();
result.handle(httpRequest, httpResponse).block();
assertEquals(HttpStatus.ACCEPTED, httpResponse.getStatusCode());
assertTrue(filterInvoked.get());
}
}