• 15、Gateway全局过滤器


    上一节学习的过滤器,网关提供了31种,但每一种过滤器的作用都是固定的。如果我们希望拦截请求,做自己的业务逻辑则没办法实现。

    1、全局过滤器作用

    全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的;而GlobalFilter的逻辑需要自己写代码实现。定义方式是实现GlobalFilter接口

    public interface GlobalFilter {
        /**
         *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
         *
         * @param exchange 请求上下文,里面可以获取Request、Response等信息
         * @param chain 用来把请求委托给下一个过滤器 
         * @return {@code Mono<Void>} 返回标示当前过滤器业务结束
         */
        Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在filter中编写自定义逻辑,可以实现下列功能:

    • 登录状态判断
    • 权限校验
    • 请求限流等

    2、自定义全局过滤器

    需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

    • 参数中是否有authorization,
    • authorization参数值是否为admin

    如果同时满足则放行,否则拦截

    实现:

    在gateway中定义一个过滤器:

    package cn.itcast.gateway.filters;
    
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.annotation.Order;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Order(-1)	//每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
    @Component
    public class AuthorizeFilter implements GlobalFilter {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 1.获取请求参数
            MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
            // 2.获取authorization参数
            String auth = params.getFirst("authorization");
            // 3.校验
            if ("admin".equals(auth)) {
                // 放行
                return chain.filter(exchange);
            }
            // 4.拦截
            // 4.1.禁止访问,设置状态码
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            // 4.2.结束处理
            return exchange.getResponse().setComplete();
        }
    }
    
    • 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

    过滤器执行顺序

    请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter

    请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器:
    在这里插入图片描述
    排序的规则是什么呢?

    • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
    • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
    • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
    • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

    详细内容,可以查看源码:

    org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。

    org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

  • 相关阅读:
    十六、商城 - 品牌管理-CRUD(4)
    Educational Codeforces Round 122 (Rated for Div. 2) D. Make Them Equal
    Linux上部署net6应用
    IDEA手动导入jar包到maven本地库
    Docker 维护
    React状态与引用(Refs)- 差异和使用场景
    一分钟每日科技速递 2022/08/14
    学习java的第十八天。。。(子类)
    深陷盈利困境,“寒冬”中也要二次递表,北森上市迫切
    (附源码)php养老院管理系统 毕业设计 202026
  • 原文地址:https://blog.csdn.net/qq_49451343/article/details/125562226