提交 59e43269 编写于 作者: A Arjen Poutsma

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()
上级 921bf5fb
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册