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