springboot webflux 过滤器(使用RouterFunction实现)

网友投稿 383 2022-08-22


springboot webflux 过滤器(使用RouterFunction实现)

目录webflux过滤器(RouterFunction实现)相关类与接口示例使用测试RouterFunction的webflux代码接下来看看routerFunction下的参数校验

webflux过滤器(RouterFunction实现)

相关类与接口

HandlerFiterFunction

@FunctionalInterface

public interface HandlerFilterFunction {

Mono filter(ServerRequest var1, HandlerFunction var2);

default HandlerFilterFunction andThen(HandlerFilterFunction after) {

Assert.notNull(after, "HandlerFilterFunction must not be null");

return (request, next) -> {

HandlerFunction nextHandler = (handlerRequest) -> {

return after.filter(handlerRequest, next);

};

return this.filter(request, nextHandler);

};

}

default HandlerFunction apply(HandlerFunction handler) {

Assert.notNull(handler, "HandlerFunction must not be null");

return (request) -> {

return this.filter(request, handler);

};

}

static HandlerFilterFunction, ?> ofRequestProcessor(Function> 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 HandlerFilterFunction ofResponseProcessor(Function> responseProcessor) {

Assert.notNull(responseProcessor, "Function must not be null");

return (request, next) -> {

return next.handle(request).flatMap(responseProcessor);

};

}

}

HandlerFunction

@FunctionalInterface

public interface HandlerFunction {

Mono handle(ServerRequest var1);

}

示例

config 层

CustomRouterConfig

@Configuration

public class CustomRouterConfig {

@Bean

public RouterFunction 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): 80802020-06-21 15:18:08.018  INFO 16336 --- [           main] com.example.demo.DemoApplication &nhttp://bsp;       : Started DemoApplication in 1.807 seconds (JVM running for 2.641)custom filterpath:/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 getAllUser(ServerRequest request){

return ServerResponse.ok().contentType(MediaType.APPLICATION_jsON)

.body(repository.findAll() , User.class);

}

public Mono createUser(ServerRequest request){

Mono userMono = request.bodyToMono(User.class);

return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)

.body(repository.saveAll(userMono) , User.class);

}

public Mono 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 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 createUser(ServerRequest request){

Mono 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 handle(ServerWebExchange serverWebExchange, Throwable throwable) {

ServerHttpResponse response = serverWebExchange.getResponse();

response.setStatusCode(HttpStatus.BAD_REQUEST);

response.getHeaders().sethttp://ContentType(MediaType.TEXT_PLAIN);

String errorMsg = toStr(throwable);

DataBuffer db = response.bufferFactory().wrap(errorMsg.getBytes());

return response.writeWith(Mono.just(db));

awPDb }

private String toStr(Throwable throwable) {

//已知异常,自定义异常,这里懒得写了,就随便找一个代替

if (throwable instanceof NumberFormatException){

NumberFormatException e = (NumberFormatException) throwable;

return e.getMessage();

}

//未知异常

else {

throwable.printStackTrace();

return throwable.toString();

}

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java泛型T,E,K,V,N,?与Object区别和含义
下一篇:springboot+jwt+微信小程序授权登录获取token的方法实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~