webflux过滤器(RouterFunction实现)
相关类与接口
HandlerFiterFunction
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
@FunctionalInterface public interface HandlerFilterFunction<T extends ServerResponse, R extends ServerResponse> { Mono<R> filter(ServerRequest var1, HandlerFunction<T> var2);
default HandlerFilterFunction<T, R> andThen(HandlerFilterFunction<T, T> after) { Assert.notNull(after, "HandlerFilterFunction must not be null" ); return (request, next) -> { HandlerFunction<T> nextHandler = (handlerRequest) -> { return after.filter(handlerRequest, next); }; return this .filter(request, nextHandler); }; }
default HandlerFunction<R> apply(HandlerFunction<T> handler) { Assert.notNull(handler, "HandlerFunction must not be null" ); return (request) -> { return this .filter(request, handler); }; }
static HandlerFilterFunction<?, ?> ofRequestProcessor(Function<ServerRequest, Mono<ServerRequest>> requestProcessor) { Assert.notNull(requestProcessor, "Function must not be null" ); return (request, next) -> { Mono var10000 = (Mono)requestProcessor.apply(request); next.getClass(); return var10000.flatMap(next::handle); }; }
static <T extends ServerResponse, R extends ServerResponse> HandlerFilterFunction<T, R> ofResponseProcessor(Function<T, Mono<R>> responseProcessor) { Assert.notNull(responseProcessor, "Function must not be null" ); return (request, next) -> { return next.handle(request).flatMap(responseProcessor); }; } } |
HandlerFunction
|
1 2 3 4 |
@FunctionalInterface public interface HandlerFunction<T extends ServerResponse> { Mono<T> handle(ServerRequest var1); } |
示例
config 层
CustomRouterConfig
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@Configuration public class CustomRouterConfig {
@Bean public RouterFunction<ServerResponse> initRouterFunction(){ return RouterFunctions.route() .GET( "/test/**" ,serverRequest -> { System.out.println( "path:" +serverRequest.exchange().getRequest().getPath().pathWithinApplication().value());
return ServerResponse.ok().bodyValue( "hello world" ); }) .filter((serverRequest, handlerFunction) -> { System.out.println( "custom filter" );
return handlerFunction.handle(serverRequest); }) .build(); } } |
使用测试
localhost:8080/test/text,控制台输出:
2020-06-21 15:18:08.005 INFO 16336 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
2020-06-21 15:18:08.018 INFO 16336 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.807 seconds (JVM running for 2.641)
custom filter
path:/test/text
RouterFunction的webflux
RouterFunction可以运行在servlet或netty上,所以我们需要将两个容器间的不同点抽象出来。
整个开发过程有几步:
1.HandleFunction,实现输入ServerRequest,输出ServerResponse
2.RouterFunction,把请求url和HandlerFunction对应起来
3.把RouterFunction包装成HttpHandler,交给容器Server处理。
代码
实体类和仓库不变
handler:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@Component public class UserHandler { private final UserRepository repository;
public UserHandler(UserRepository repository) { this .repository = repository; }
public Mono<ServerResponse> getAllUser(ServerRequest request){ return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON) .body(repository.findAll() , User. class ); } public Mono<ServerResponse> createUser(ServerRequest request){ Mono<User> userMono = request.bodyToMono(User. class ); return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON) .body(repository.saveAll(userMono) , User. class ); } public Mono<ServerResponse> deleteUserById(ServerRequest request){ String id = request.pathVariable( "id" ); return this .repository.findById(id) .flatMap(user -> this .repository.delete(user) .then(ServerResponse.ok().build())) .switchIfEmpty(ServerResponse.notFound().build()); } } |
router:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Configuration public class AllRouters { @Bean RouterFunction<ServerResponse> userRouter(UserHandler handler){ return RouterFunctions.nest( //相当于requestMapping RequestPredicates.path( "/user" ) , RouterFunctions.route(RequestPredicates.GET( "/" ) , handler::getAllUser) .andRoute(RequestPredicates.POST( "/" ).and(RequestPredicates.accept(MediaType.APPLICATION_JSON)) , handler::createUser) .andRoute(RequestPredicates.DELETE( "/{id}" ) , handler::deleteUserById));
} } |
接下来看看routerFunction下的参数校验
改造下代码(这里只写一个做例子)
|
1 2 3 4 5 6 7 8 9 |
public Mono<ServerResponse> createUser(ServerRequest request){ Mono<User> userMono = request.bodyToMono(User. class ); return userMono.flatMap(user -> { //在这里做校验 //xxx return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON) .body(repository.saveAll(userMono) , User. class ); }); } |
异常捕获,用aop的方式:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
@Component @Order (- 99 ) public class ExceptionHandler implements WebExceptionHandler { @Override public Mono<Void> handle(ServerWebExchange serverWebExchange, Throwable throwable) { ServerHttpResponse response = serverWebExchange.getResponse(); response.setStatusCode(HttpStatus.BAD_REQUEST); response.getHeaders().setContentType(MediaType.TEXT_PLAIN); String errorMsg = toStr(throwable); DataBuffer db = response.bufferFactory().wrap(errorMsg.getBytes()); return response.writeWith(Mono.just(db)); }
private String toStr(Throwable throwable) { //已知异常,自定义异常,这里懒得写了,就随便找一个代替 if (throwable instanceof NumberFormatException){ NumberFormatException e = (NumberFormatException) throwable; return e.getMessage(); } //未知异常 else { throwable.printStackTrace(); return throwable.toString(); } } } |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
原文链接:https://blog.csdn.net/weixin_43931625/article/details/106882603
查看更多关于springboot webflux 过滤器(使用RouterFunction实现)的详细内容...