Various improvements to web.reactive.function
This commit introduces the following changes to web.reactive.function: - Added RouterFunction.andRoute(), a combination of RouterFunction.and() with RouterFunctions.route() - ServerRequest.pathVariable() returns String instead of Optional<String>. An exception is thrown if the variable is not present. - Added HandlerFilterFunction.andThen and HandlerFilterFunction.apply()
This commit is contained in:
parent
921bf5fb70
commit
59e4326989
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.web.reactive.function;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.support.ServerRequestWrapper;
|
||||
|
||||
/**
|
||||
|
@ -43,4 +44,30 @@ public interface HandlerFilterFunction<T, R> {
|
|||
*/
|
||||
ServerResponse<R> filter(ServerRequest request, HandlerFunction<T> next);
|
||||
|
||||
/**
|
||||
* Return a composed filter function that first applies this filter, and then applies the
|
||||
* {@code after} filter.
|
||||
* @param after the filter to apply after this filter is applied
|
||||
* @return a composed filter that first applies this function and then applies the
|
||||
* {@code after} function
|
||||
*/
|
||||
default HandlerFilterFunction<T, R> andThen(HandlerFilterFunction<T, T> after) {
|
||||
Assert.notNull(after, "'after' must not be null");
|
||||
return (request, next) -> {
|
||||
HandlerFunction<T> nextHandler =
|
||||
handlerRequest -> after.filter(handlerRequest, next);
|
||||
return filter(request, nextHandler);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply this filter to the given handler function, resulting in a filtered handler function.
|
||||
* @param handler the handler function to filter
|
||||
* @return the filtered handler function
|
||||
*/
|
||||
default HandlerFunction<R> apply(HandlerFunction<T> handler) {
|
||||
Assert.notNull(handler, "'handler' must not be null");
|
||||
return request -> this.filter(request, handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ public abstract class RequestPredicates {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> pathVariable(String name) {
|
||||
public String pathVariable(String name) {
|
||||
return this.request.pathVariable(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,22 @@ public interface RouterFunction<T> {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a composed routing function that first invokes this function,
|
||||
* and then routes to the given handler function if the given request predicate applies. This
|
||||
* method is a convenient combination of {@link #and(RouterFunction)} and
|
||||
* {@link RouterFunctions#route(RequestPredicate, HandlerFunction)}.
|
||||
* @param predicate the predicate to test
|
||||
* @param handlerFunction the handler function to route to
|
||||
* @return a composed function that first routes with this function and then the function
|
||||
* created from {@code predicate} and {@code handlerFunction} if this
|
||||
* function has no result
|
||||
*/
|
||||
default RouterFunction<?> andRoute(RequestPredicate predicate,
|
||||
HandlerFunction<?> handlerFunction) {
|
||||
return and(RouterFunctions.route(predicate, handlerFunction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter all {@linkplain HandlerFunction handler functions} routed by this function with the given
|
||||
* {@linkplain HandlerFilterFunction filter function}.
|
||||
|
@ -80,8 +96,7 @@ public interface RouterFunction<T> {
|
|||
* @return the filtered routing function
|
||||
*/
|
||||
default <S> RouterFunction<S> filter(HandlerFilterFunction<T, S> filterFunction) {
|
||||
return request -> this.route(request)
|
||||
.map(handlerFunction -> filterRequest -> filterFunction.filter(filterRequest, handlerFunction));
|
||||
return request -> this.route(request).map(filterFunction::apply);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -101,9 +101,17 @@ public interface ServerRequest {
|
|||
* Return the path variable with the given name, if present.
|
||||
* @param name the variable name
|
||||
* @return the variable value
|
||||
* @throws IllegalArgumentException if there is no path variable with the given name
|
||||
*/
|
||||
default Optional<String> pathVariable(String name) {
|
||||
return Optional.ofNullable(this.pathVariables().get(name));
|
||||
default String pathVariable(String name) {
|
||||
Map<String, String> pathVariables = pathVariables();
|
||||
if (pathVariables.containsKey(name)) {
|
||||
return pathVariables().get(name);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"No path variable with name \"" + name + "\" available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -104,7 +104,7 @@ public class ServerRequestWrapper implements ServerRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> pathVariable(String name) {
|
||||
public String pathVariable(String name) {
|
||||
return this.request.pathVariable(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,15 @@ public class DefaultServerRequestTests {
|
|||
Map<String, String> pathVariables = Collections.singletonMap("foo", "bar");
|
||||
when(mockExchange.getAttribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE)).thenReturn(Optional.of(pathVariables));
|
||||
|
||||
assertEquals(Optional.of("bar"), defaultRequest.pathVariable("foo"));
|
||||
assertEquals("bar", defaultRequest.pathVariable("foo"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void pathVariableNotFound() throws Exception {
|
||||
Map<String, String> pathVariables = Collections.singletonMap("foo", "bar");
|
||||
when(mockExchange.getAttribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE)).thenReturn(Optional.of(pathVariables));
|
||||
|
||||
assertEquals("bar", defaultRequest.pathVariable("baz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -116,9 +116,9 @@ public class ServerRequestWrapperTests {
|
|||
public void pathVariable() throws Exception {
|
||||
String name = "foo";
|
||||
String value = "bar";
|
||||
when(mockRequest.pathVariable(name)).thenReturn(Optional.of(value));
|
||||
when(mockRequest.pathVariable(name)).thenReturn(value);
|
||||
|
||||
assertEquals(Optional.of(value), wrapper.pathVariable(name));
|
||||
assertEquals(value, wrapper.pathVariable(name));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue