好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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实现)的详细内容...

  阅读:31次