springboot webflux 过滤器(使用RouterFunction实现)
作者:o_瓜田李下_o 时间:2022-12-12 21:28:44
webflux过滤器(RouterFunction实现)
相关类与接口
HandlerFiterFunction
@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
@FunctionalInterface
public interface HandlerFunction<T extends ServerResponse> {
Mono<T> handle(ServerRequest var1);
}
示例
config 层
CustomRouterConfig
@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:
@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:
@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下的参数校验
改造下代码(这里只写一个做例子)
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的方式:
@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