spring gateway 自定义sessionmanager_SpringCloud系列Gateway:自定义过滤器

本文详细介绍了如何在Spring Cloud Gateway中自定义网关过滤器和全局过滤器。通过实现GatewayFilter接口和GatewayFilterFactory接口,以及利用AbstractGatewayFilterFactory抽象类,展示了自定义过滤器的实现过程。同时,文章还提到了自定义全局过滤器需要实现GlobalFilter和Ordered接口,用于实现如权限校验等高级功能。

通过上一篇文章SpringCloud系列Gateway:过滤器总结我们知道Gateway的过滤器分为网关过滤器和全局过滤器,今天带大家看看如何自定义这两种过滤器。

自定义网关过滤器

自定义网关过滤器有两种实现方式

  1. 实现GatewayFilter接口
  2. 实现GatewayFilterFactory接口

下面针对两种方式分别介绍

实现GatewayFilter接口

  1. 自定义过滤器
/** * 自定义网关过滤器 * @author  yanyu */@Slf4jpublic class CustomGatewayFilter implements GatewayFilter, Ordered {    /**     * 过滤器业务     * @param exchange     * @param chain     * @return     */    @Override    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        log.info("自定义过滤器...");        return chain.filter(exchange);    }    /**     * 过滤器的执行顺序,值越小,优先级越高     * @return     */    @Override    public int getOrder() {        return 0;    }}
  1. 注册过滤器
@Configurationpublic class GatewayFilterConfig {    @Bean    public RouteLocator routeLocator(RouteLocatorBuilder builder) {        return builder.routes().route(r-> r                // 断言                .path("/product/**")                // 目标URI                .uri("http://localhost:8890")                // 过滤器                .filters(new CustomGatewayFilter())                // 路由ID                .id("product-service")).build();    }}
  1. 修改文件配置,我们通过RouteLocatorBuilder创建路由规则,所以在配置文件中我们不需要再增加路由规则,如下配置
server:  port: 8892spring:  application:    name: gateway-server
  1. 测试,自定义过滤器被执行
359c4fe7a0fa0cb11b8c1cd58a09505d.png

实现GatewayFilterFactory接口

GatewayFilterFactory类分析

@FunctionalInterfacepublic interface GatewayFilterFactory extends ShortcutConfigurable, Configurable {    // 对过滤器标准化命名    default String name() {        // TODO: deal with proxys        return NameUtils.normalizeFilterFactoryName(getClass());    }        // 过滤器创建    default GatewayFilter apply(Consumer consumer) {        C config = newConfig();        consumer.accept(config);        return apply(config);    }        // 留给子类实现    GatewayFilter apply(C config);}

在接口名称上加有@FunctionalInterface 注解,可以知道GatewayFilterFactory是一个函数式接口,该类中有两个比较重要的方法。

  • default类型的name方法,用来给过滤器标准化命名
  • default类型的apply方法,该方法最终会调用子类的apply实现,泛型C为实现类的配置对象。

GatewayFilterFactory类继承关系

18b51b6d5ad415b25bd0658b4b13c7ec.png

在类继承关系中,比较重要的有四个类

  • GatewayFilterFactory:顶级接口
  • AbstractGatewayFilterFactory:实现GatewayFilterFacotry抽象类
  • AbstractNameValueGatewayFilterFactory:该抽象类用于提供通用的方法给键值对参数类型的网关过滤器,接收两个参数,具体可以看上文的【Parameter请求参数过滤器】配置
  • AbstractChangeRequestUriGatewayFilterFactory:改变请求的 URI 过滤器,该过滤器通过方法 determineRequestUri( ServerWebExchange,T)实现改变请求URI的逻辑

从GatewayFilterFactory类继承图上可以看到,过滤器工厂都实现 ShortcutConfigurable 接口。

public interface ShortcutConfigurable {    default ShortcutConfigurable.ShortcutType shortcutType() {        return ShortcutConfigurable.ShortcutType.DEFAULT;    }    default List shortcutFieldOrder() {        return Collections.emptyList();    }    public static enum ShortcutType {        DEFAULT {          ...省略        },        GATHER_LIST {           ...省略        },        GATHER_LIST_TAIL_FLAG {           ...省略        };    }}

接下来重点讲一下ShortcutConfigurable类,该类主要作用是指定过滤器自身配置对象参数的个数和顺序。

过滤器工厂和断言工厂都继承了ShortcutConfigurable类,关于配置对象可以看以前的文章【Spring Cloud系列Gateway:自定义断言规则】讲解

ShortcutConfigurable类规则包括以下几种:

  • DEFAULT : 按照shortcutFieldOrder顺序依次赋值
  • GATHER_LIST:shortcutFiledOrder只能有一个参数,如果值有多个拼成一个集合
  • GATHER_LIST_TAIL_FLAG:shortcutFiledOrder只能有两个参数,其中最后一个值为true或者false,其余的值变成一个集合付给第一个参数

通过GatewayFilterFactory自定义网关过滤器

下面简单的介绍一下如何自定义网关过滤器。实现有三步步骤,如下所示

  1. 修改配置文件
spring:  profiles: customFilter  cloud:    gateway:      routes:        - id: product-service         # 路由ID 唯一          uri: http://localhost:8890  # 目标URL,路由到对应的微服务地址          predicates:            - Path=/product/**   # 匹配对应URL请求,将匹配的请求追加到目标URI之后          filters:            - RequestLog=test1,test2
  1. 实现AbstractNameValueGatewayFilterFactory抽象类,自定义网关过滤器工厂并将该类注册到Spring上下文中
@Slf4j@Componentpublic class RequestLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {    @Override    public GatewayFilter apply(NameValueConfig config) {        return (exchange,  chain)-> {            log.info("请求网关:{},{}",config.getName(),config.getValue());            MultiValueMap params = exchange.getRequest().getQueryParams();            params.forEach((k,v)->{                log.info("请求参数:{},请求参数值:{}",k, StringUtils.join(v,","));            });            return chain.filter(exchange).then();        };    }}

AbstractNameValueGatewayFilterFactory已经定义了配置类,所以不需要我们再手动定义配置类,直接使用该配置类,具体可以看AbstractNameValueGatewayFilterFactory.NameValueConfig类

  1. 测试调用http://localhost:8892/product/1?test=测试自定义网关过滤器
02de760759755c8eeaca8cd57a11635b.png

自定义全局过滤器

自定义全局过滤器需要实现以下两个接口:GlobalFilter,Ordered,通过全局过滤器可以实现权限校验,安全性验证等功能。

  1. 定义全局过滤器,并将该类注册到Spring上下文中
@Component@Slf4jpublic class CustomGlobalFilter implements GlobalFilter, Ordered {    @Override    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        log.info("自定义全局过滤器...");        return chain.filter(exchange);    }    @Override    public int getOrder() {        return 0;    }}
  1. 测试
c793638c63b5c09c647d2ff0f8cb31d0.png

如果有哪里写得不对的,还请各位小友指正,只有不断试错,才能慢慢提高。如果你觉得对你有帮助,请点赞+关注,谢谢!!!!!!

想要源码的小伙伴,可以点击关注,私信!!!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值