@Override public Mono<HandlerFunction<S>> route(ServerRequest request) { return this.routerFunction.route(request).map(this.filterFunction::apply); }
@Override protected Mono<?> getHandlerInternal(ServerWebExchange exchange) { if (this.routerFunction != null) { ServerRequest request = ServerRequest.create(exchange, this.messageReaders); return this.routerFunction.route(request) .doOnNext(handler -> setAttributes(exchange.getAttributes(), request, handler)); } else { return Mono.empty(); } }
@Override public Mono<HandlerFunction<T>> route(ServerRequest serverRequest) { return this.predicate.nest(serverRequest) .map(nestedRequest -> { if (logger.isTraceEnabled()) { String logPrefix = serverRequest.exchange().getLogPrefix(); logger.trace(logPrefix + String.format("Matched nested %s", this.predicate)); } return this.routerFunction.route(nestedRequest) .doOnNext(match -> { if (nestedRequest != serverRequest) { serverRequest.attributes().clear(); serverRequest.attributes() .putAll(nestedRequest.attributes()); } }); } ).orElseGet(Mono::empty); }
/** * Convert the given {@linkplain RouterFunction router function} into a {@link WebHandler}, * using the given strategies. * @param routerFunction the router function to convert * @param strategies the strategies to use * @return a web handler that handles web request using the given router function */ public static WebHandler toWebHandler(RouterFunction<?> routerFunction, HandlerStrategies strategies) { Assert.notNull(routerFunction, "RouterFunction must not be null"); Assert.notNull(strategies, "HandlerStrategies must not be null"); return exchange -> { ServerRequest request = new DefaultServerRequest(exchange, strategies.messageReaders()); addAttributes(exchange, request); return routerFunction.route(request) .defaultIfEmpty(notFound()) .flatMap(handlerFunction -> wrapException(() -> handlerFunction.handle(request))) .flatMap(response -> wrapException(() -> response.writeTo(exchange, new HandlerStrategiesResponseContext(strategies)))); }; }
@Test public void nestNoMatch() { HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build(); RouterFunction<ServerResponse> routerFunction = request -> Mono.just(handlerFunction); MockServerRequest request = MockServerRequest.builder().build(); RequestPredicate requestPredicate = mock(RequestPredicate.class); when(requestPredicate.nest(request)).thenReturn(Optional.empty()); RouterFunction<ServerResponse> result = RouterFunctions.nest(requestPredicate, routerFunction); assertNotNull(result); Mono<HandlerFunction<ServerResponse>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectComplete() .verify(); }
@Test public void nestMatch() { HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build(); RouterFunction<ServerResponse> routerFunction = request -> Mono.just(handlerFunction); MockServerRequest request = MockServerRequest.builder().build(); RequestPredicate requestPredicate = mock(RequestPredicate.class); when(requestPredicate.nest(request)).thenReturn(Optional.of(request)); RouterFunction<ServerResponse> result = RouterFunctions.nest(requestPredicate, routerFunction); assertNotNull(result); Mono<HandlerFunction<ServerResponse>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectNext(handlerFunction) .expectComplete() .verify(); }
@Test public void routeNoMatch() { HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build(); MockServerRequest request = MockServerRequest.builder().build(); RequestPredicate requestPredicate = mock(RequestPredicate.class); when(requestPredicate.test(request)).thenReturn(false); RouterFunction<ServerResponse> result = RouterFunctions.route(requestPredicate, handlerFunction); assertNotNull(result); Mono<HandlerFunction<ServerResponse>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectComplete() .verify(); }
@Test public void resources() { Resource resource = new ClassPathResource("/org/springframework/web/reactive/function/server/"); assertTrue(resource.exists()); RouterFunction<ServerResponse> route = RouterFunctions.route() .resources("/resources/**", resource) .build(); MockServerRequest resourceRequest = MockServerRequest.builder(). method(HttpMethod.GET). uri(URI.create("http://localhost/resources/response.txt")) .build(); Mono<Integer> responseMono = route.route(resourceRequest) .flatMap(handlerFunction -> handlerFunction.handle(resourceRequest)) .map(ServerResponse::statusCode) .map(HttpStatus::value); StepVerifier.create(responseMono) .expectNext(200) .verifyComplete(); MockServerRequest invalidRequest = MockServerRequest.builder(). method(HttpMethod.POST). uri(URI.create("http://localhost/resources/foo.txt")) .build(); responseMono = route.route(invalidRequest) .flatMap(handlerFunction -> handlerFunction.handle(invalidRequest)) .map(ServerResponse::statusCode) .map(HttpStatus::value); StepVerifier.create(responseMono) .verifyComplete(); }
@Test public void routeMatch() { HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build(); MockServerRequest request = MockServerRequest.builder().build(); RequestPredicate requestPredicate = mock(RequestPredicate.class); when(requestPredicate.test(request)).thenReturn(true); RouterFunction<ServerResponse> result = RouterFunctions.route(requestPredicate, handlerFunction); assertNotNull(result); Mono<HandlerFunction<ServerResponse>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectNext(handlerFunction) .expectComplete() .verify(); }
@Test public void andOther() { HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().body(fromObject("42")); RouterFunction<?> routerFunction1 = request -> Mono.empty(); RouterFunction<ServerResponse> routerFunction2 = request -> Mono.just(handlerFunction); RouterFunction<?> result = routerFunction1.andOther(routerFunction2); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); Mono<? extends HandlerFunction<?>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectNextMatches(o -> o.equals(handlerFunction)) .expectComplete() .verify(); }
@Test public void andRoute() { RouterFunction<ServerResponse> routerFunction1 = request -> Mono.empty(); RequestPredicate requestPredicate = request -> true; RouterFunction<ServerResponse> result = routerFunction1.andRoute(requestPredicate, this::handlerMethod); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); Mono<? extends HandlerFunction<?>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectNextCount(1) .expectComplete() .verify(); }
@Test public void and() { HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build(); RouterFunction<ServerResponse> routerFunction1 = request -> Mono.empty(); RouterFunction<ServerResponse> routerFunction2 = request -> Mono.just(handlerFunction); RouterFunction<ServerResponse> result = routerFunction1.and(routerFunction2); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); Mono<HandlerFunction<ServerResponse>> resultHandlerFunction = result.route(request); StepVerifier.create(resultHandlerFunction) .expectNext(handlerFunction) .expectComplete() .verify(); }
.build(); Mono<Integer> responseMono = route.route(fooRequest) .flatMap(handlerFunction -> handlerFunction.handle(fooRequest)) .map(ServerResponse::statusCode) .build(); responseMono = route.route(barRequest) .flatMap(handlerFunction -> handlerFunction.handle(barRequest)) .map(ServerResponse::statusCode) .build(); responseMono = route.route(invalidRequest) .flatMap(handlerFunction -> handlerFunction.handle(invalidRequest)) .map(ServerResponse::statusCode)
@Test public void nest() { RouterFunction<?> route = RouterFunctions.route() .path("/foo", builder -> builder.path("/bar", () -> RouterFunctions.route() .GET("/baz", request -> ServerResponse.ok().build()) .build())) .build(); MockServerRequest fooRequest = MockServerRequest.builder(). method(HttpMethod.GET). uri(URI.create("http://localhost/foo/bar/baz")) .build(); Mono<Integer> responseMono = route.route(fooRequest) .flatMap(handlerFunction -> handlerFunction.handle(fooRequest)) .map(ServerResponse::statusCode) .map(HttpStatus::value); StepVerifier.create(responseMono) .expectNext(200) .verifyComplete(); }
@Test public void filter() { Mono<String> stringMono = Mono.just("42"); HandlerFunction<EntityResponse<Mono<String>>> handlerFunction = request -> EntityResponse.fromPublisher(stringMono, String.class).build(); RouterFunction<EntityResponse<Mono<String>>> routerFunction = request -> Mono.just(handlerFunction); HandlerFilterFunction<EntityResponse<Mono<String>>, EntityResponse<Mono<Integer>>> filterFunction = (request, next) -> next.handle(request).flatMap( response -> { Mono<Integer> intMono = response.entity() .map(Integer::parseInt); return EntityResponse.fromPublisher(intMono, Integer.class).build(); }); RouterFunction<EntityResponse<Mono<Integer>>> result = routerFunction.filter(filterFunction); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); Mono<EntityResponse<Mono<Integer>>> responseMono = result.route(request).flatMap(hf -> hf.handle(request)); StepVerifier.create(responseMono) .consumeNextWith( serverResponse -> { StepVerifier.create(serverResponse.entity()) .expectNext(42) .expectComplete() .verify(); }) .expectComplete() .verify(); }
/** * Return a composed routing function that first invokes this function, * and then invokes the {@code other} function (of the same type {@code T}) if this route had * {@linkplain Mono#empty() no result}. * * @param other the function of type {@code T} to apply when this function has no result * @return a composed function that first routes with this function and then the {@code other} function if this * function has no result */ default RouterFunction<T> andSame(RouterFunction<T> other) { return request -> this.route(request).otherwiseIfEmpty(other.route(request)); }
@Override public Mono<Object> getHandler(ServerWebExchange exchange) { ServerRequest request = new DefaultServerRequest(exchange, strategies); addAttributes(exchange, request); return routerFunction.route(request).map(handlerFunction -> (Object)handlerFunction); } };