From 228a01b298658096f0e6d3108eca3c16a52ddee7 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 16 Sep 2016 11:13:53 +0200 Subject: [PATCH] Polishing --- .../web/reactive/function/CastingUtils.java | 31 -------- .../reactive/function/RoutingFunction.java | 5 +- .../reactive/function/RoutingFunctions.java | 65 +++++++++------- .../support/ResponseResultHandler.java | 11 ++- .../function/DefaultResponseBuilderTests.java | 76 ------------------- ...lisherHandlerFunctionIntegrationTests.java | 7 +- 6 files changed, 52 insertions(+), 143 deletions(-) delete mode 100644 spring-web-reactive/src/main/java/org/springframework/web/reactive/function/CastingUtils.java diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/CastingUtils.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/CastingUtils.java deleted file mode 100644 index 5aba8f82860..00000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/CastingUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.reactive.function; - -/** - * @author Arjen Poutsma - */ -@SuppressWarnings("unchecked") -abstract class CastingUtils { - - - public static HandlerFunction cast(HandlerFunction handlerFunction) { - return (HandlerFunction) handlerFunction; - } - - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunction.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunction.java index c037517edf0..56970d09a67 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunction.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunction.java @@ -24,6 +24,7 @@ import java.util.Optional; * @param the type of the {@linkplain HandlerFunction handler function} to route to * @author Arjen Poutsma * @since 5.0 + * @see RoutingFunctions */ @FunctionalInterface public interface RoutingFunction { @@ -64,9 +65,9 @@ public interface RoutingFunction { default RoutingFunction and(RoutingFunction other) { return request -> { Optional> result = this.route(request). - map(CastingUtils::cast); + map(RoutingFunctions::cast); return result.isPresent() ? result : other.route(request) - .map(CastingUtils::cast); + .map(RoutingFunctions::cast); }; } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunctions.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunctions.java index 24860ac254a..c0fa797eb67 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunctions.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RoutingFunctions.java @@ -28,25 +28,23 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.adapter.HttpWebHandlerAdapter; /** - * Central entry point Spring's functional web framework. + * Central entry point to Spring's functional web framework. * Exposes routing functionality, such as to - * {@linkplain #route(RequestPredicate, HandlerFunction) create} a {@link RoutingFunction} given a - * {@link RequestPredicate} and {@link HandlerFunction}, and to do further + * {@linkplain #route(RequestPredicate, HandlerFunction) create} a {@code RoutingFunction} given a + * {@code RequestPredicate} and {@code HandlerFunction}, and to do further * {@linkplain #subroute(RequestPredicate, RoutingFunction) subrouting} on an existing routing * function. * *

Additionally, this class can {@linkplain #toHttpHandler(RoutingFunction) transform} a - * {@link RoutingFunction} into an {@link HttpHandler}, which can be run in - * {@linkplain org.springframework.http.server.reactive.ServletHttpHandlerAdapter Servlet 3.1+}, - * {@linkplain org.springframework.http.server.reactive.ReactorHttpHandlerAdapter Reactor}, - * {@linkplain org.springframework.http.server.reactive.RxNettyHttpHandlerAdapter RxNetty}, or - * {@linkplain org.springframework.http.server.reactive.UndertowHttpHandlerAdapter Undertow}. - * Or it {@linkplain #toHandlerMapping(RoutingFunction, Configuration) transform} a - * {@link RoutingFunction} into an {@link HandlerMapping}, which can be run in a - * {@link org.springframework.web.reactive.DispatcherHandler DispatcherHandler}. + * {@code RoutingFunction} into an {@code HttpHandler}, which can be run in Servlet 3.1+, + * Reactor, RxNetty, or Undertow. + * And it can {@linkplain #toHandlerMapping(RoutingFunction, Configuration) transform} a + * {@code RoutingFunction} into an {@code HandlerMapping}, which can be run in a + * {@code DispatcherHandler}. * * @author Arjen Poutsma * @since 5.0 + * */ public abstract class RoutingFunctions { @@ -57,13 +55,6 @@ public abstract class RoutingFunctions { */ public static final String REQUEST_ATTRIBUTE = RoutingFunctions.class.getName() + ".request"; - /** - * Name of the {@link ServerWebExchange} attribute that contains the - * {@linkplain Configuration configuration} used throughout the routing and handling of the - * request. - */ - public static final String CONFIGURATION_ATTRIBUTE = RoutingFunctions.class.getName() + ".configuration"; - /** * Name of the {@link ServerWebExchange} attribute that contains the URI * templates map, mapping variable names to values. @@ -115,10 +106,16 @@ public abstract class RoutingFunctions { * This conversion uses the {@linkplain Configuration#builder() default configuration}. * *

The returned {@code HttpHandler} can be adapted to run in - * {@linkplain org.springframework.http.server.reactive.ServletHttpHandlerAdapter Servlet 3.1+}, - * {@linkplain org.springframework.http.server.reactive.ReactorHttpHandlerAdapter Reactor}, - * {@linkplain org.springframework.http.server.reactive.RxNettyHttpHandlerAdapter RxNetty}, or - * {@linkplain org.springframework.http.server.reactive.UndertowHttpHandlerAdapter Undertow}. + *

    + *
  • Servlet 3.1+ using the + * {@link org.springframework.http.server.reactive.ServletHttpHandlerAdapter},
  • + *
  • Reactor using the + * {@link org.springframework.http.server.reactive.ReactorHttpHandlerAdapter},
  • + *
  • RxNetty using the + * {@link org.springframework.http.server.reactive.RxNettyHttpHandlerAdapter}, or
  • + *
  • Undertow using the + * {@link org.springframework.http.server.reactive.UndertowHttpHandlerAdapter}.
  • + *
* * @param routingFunction the routing function to convert * @return an http handler that handles HTTP request using the given routing function @@ -132,10 +129,16 @@ public abstract class RoutingFunctions { * using the given configuration. * *

The returned {@code HttpHandler} can be adapted to run in - * {@linkplain org.springframework.http.server.reactive.ServletHttpHandlerAdapter Servlet 3.1+}, - * {@linkplain org.springframework.http.server.reactive.ReactorHttpHandlerAdapter Reactor}, - * {@linkplain org.springframework.http.server.reactive.RxNettyHttpHandlerAdapter RxNetty}, or - * {@linkplain org.springframework.http.server.reactive.UndertowHttpHandlerAdapter Undertow}. + *

    + *
  • Servlet 3.1+ using the + * {@link org.springframework.http.server.reactive.ServletHttpHandlerAdapter},
  • + *
  • Reactor using the + * {@link org.springframework.http.server.reactive.ReactorHttpHandlerAdapter},
  • + *
  • RxNetty using the + * {@link org.springframework.http.server.reactive.RxNettyHttpHandlerAdapter}, or
  • + *
  • Undertow using the + * {@link org.springframework.http.server.reactive.UndertowHttpHandlerAdapter}.
  • + *
* * @param routingFunction the routing function to convert * @param configuration the configuration to use @@ -156,10 +159,10 @@ public abstract class RoutingFunctions { } /** - * Converts the given {@linkplain RoutingFunction routing function} into a {@link HandlerMapping}. + * Converts the given {@code RoutingFunction} into a {@code HandlerMapping}. * This conversion uses the {@linkplain Configuration#builder() default configuration}. * - *

The returned {@code HttpHandler} can be run in a + *

The returned {@code HandlerMapping} can be run in a * {@link org.springframework.web.reactive.DispatcherHandler}. * * @param routingFunction the routing function to convert @@ -175,7 +178,7 @@ public abstract class RoutingFunctions { * Converts the given {@linkplain RoutingFunction routing function} into a {@link HandlerMapping} * using the given configuration. * - *

The returned {@code HttpHandler} can be run in a + *

The returned {@code HandlerMapping} can be run in a * {@link org.springframework.web.reactive.DispatcherHandler}. * * @param routingFunction the routing function to convert @@ -210,4 +213,8 @@ public abstract class RoutingFunctions { return (HandlerFunction) NOT_FOUND_HANDLER; } + @SuppressWarnings("unchecked") + static HandlerFunction cast(HandlerFunction handlerFunction) { + return (HandlerFunction) handlerFunction; + } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/support/ResponseResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/support/ResponseResultHandler.java index 25a19ad1d36..d965023746a 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/support/ResponseResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/support/ResponseResultHandler.java @@ -35,10 +35,16 @@ public class ResponseResultHandler implements HandlerResultHandler { private final Configuration configuration; + /** + * Create a {@code ResponseResultHandler} with a default configuration. + */ public ResponseResultHandler() { this(Configuration.builder().build()); } + /** + * Create a {@code ResponseResultHandler} with the given configuration. + */ public ResponseResultHandler(Configuration configuration) { Assert.notNull(configuration, "'configuration' must not be null"); this.configuration = configuration; @@ -46,8 +52,9 @@ public class ResponseResultHandler implements HandlerResultHandler { @Override public boolean supports(HandlerResult result) { - Object returnValue = result.getReturnValue().orElse(null); - return returnValue instanceof Response; + return result.getReturnValue() + .filter(o -> o instanceof Response) + .isPresent(); } @Override diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java index cd691e4ee57..0c83c91994d 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java @@ -213,7 +213,6 @@ public class DefaultResponseBuilderTests { assertNull(response.getBody()); } - @SuppressWarnings("rawtypes") @Test public void bodyPopulator() throws Exception { String body = "foo"; @@ -246,81 +245,6 @@ public class DefaultResponseBuilderTests { assertNotNull(response.getBody()); } - /* - - @Test - public void bodyNotAcceptable() throws Exception { - String body = "foo"; - Response result = Response.ok().contentType(MediaType.APPLICATION_JSON).body(body); - assertEquals(body, result.body()); - - MockServerHttpRequest request = - new MockServerHttpRequest(HttpMethod.GET, "http://localhost"); - MockServerHttpResponse response = new MockServerHttpResponse(); - ServerWebExchange exchange = - new DefaultServerWebExchange(request, response, new MockWebSessionManager()); - - List> messageWriters = new ArrayList<>(); - messageWriters.add(new EncoderHttpMessageWriter(new CharSequenceEncoder())); - - Configuration configuration = mock(Configuration.class); - when(configuration.messageWriters()).thenReturn(messageWriters::stream); - - result.writeTo(exchange, configuration).block(); - assertEquals(HttpStatus.NOT_ACCEPTABLE, response.getStatusCode()); - } - - @Test - public void stream() throws Exception { - Publisher publisher = Flux.just("foo", "bar"); - Response> result = Response.ok().stream(publisher, String.class); - - MockServerHttpRequest request = - new MockServerHttpRequest(HttpMethod.GET, "http://localhost"); - MockServerHttpResponse response = new MockServerHttpResponse(); - ServerWebExchange exchange = - new DefaultServerWebExchange(request, response, new MockWebSessionManager()); - - List> messageWriters = new ArrayList<>(); - messageWriters.add(new EncoderHttpMessageWriter(new CharSequenceEncoder())); - - Configuration mockConfig = mock(Configuration.class); - when(mockConfig.messageWriters()).thenReturn(messageWriters::stream); - exchange.getAttributes().put(RoutingFunctions.CONFIGURATION_ATTRIBUTE, mockConfig); - - result.writeTo(exchange).block(); - assertNotNull(response.getBody()); - } - - @Test - public void resource() throws Exception { - Resource resource = new ClassPathResource("response.txt", DefaultResponseBuilderTests.class); - Response result = Response.ok().resource(resource); - - ServerWebExchange exchange = mock(ServerWebExchange.class); - MockServerHttpResponse response = new MockServerHttpResponse(); - when(exchange.getResponse()).thenReturn(response); - - - result.writeTo(exchange).block(); - assertNotNull(response.getBody()); - } - - @Test - public void sse() throws Exception { - ServerSentEvent sse = ServerSentEvent.builder().data("42").build(); - Mono> body = Mono.just(sse); - Response>> result = Response.ok().sse(body); - - ServerWebExchange exchange = mock(ServerWebExchange.class); - MockServerHttpResponse response = new MockServerHttpResponse(); - when(exchange.getResponse()).thenReturn(response); - - result.writeTo(exchange).block(); - assertNotNull(response.getBodyWithFlush()); - } - */ - @Test public void render() throws Exception { Map model = Collections.singletonMap("foo", "bar"); diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherHandlerFunctionIntegrationTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherHandlerFunctionIntegrationTests.java index 8710025df10..c399f907d18 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherHandlerFunctionIntegrationTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherHandlerFunctionIntegrationTests.java @@ -34,6 +34,7 @@ import org.springframework.web.client.RestTemplate; import static org.junit.Assert.assertEquals; import static org.springframework.web.reactive.function.BodyExtractors.toMono; +import static org.springframework.web.reactive.function.BodyPopulators.fromPublisher; import static org.springframework.web.reactive.function.RequestPredicates.GET; import static org.springframework.web.reactive.function.RequestPredicates.POST; import static org.springframework.web.reactive.function.RoutingFunctions.route; @@ -98,19 +99,19 @@ public class PublisherHandlerFunctionIntegrationTests public Response> mono(Request request) { Person person = new Person("John"); - return Response.ok().body(BodyPopulators.fromPublisher(Mono.just(person), Person.class)); + return Response.ok().body(fromPublisher(Mono.just(person), Person.class)); } public Response> postMono(Request request) { Mono personMono = request.body(toMono(Person.class)); - return Response.ok().body(BodyPopulators.fromPublisher(personMono, Person.class)); + return Response.ok().body(fromPublisher(personMono, Person.class)); } public Response> flux(Request request) { Person person1 = new Person("John"); Person person2 = new Person("Jane"); return Response.ok().body( - BodyPopulators.fromPublisher(Flux.just(person1, person2), Person.class)); + fromPublisher(Flux.just(person1, person2), Person.class)); } }