通过上一篇文章SpringCloud系列Gateway:过滤器总结我们知道Gateway的过滤器分为网关过滤器和全局过滤器,今天带大家看看如何自定义这两种过滤器。
自定义网关过滤器
自定义网关过滤器有两种实现方式
- 实现GatewayFilter接口
- 实现GatewayFilterFactory接口
下面针对两种方式分别介绍
实现GatewayFilter接口
- 自定义过滤器
/** * 自定义网关过滤器 * @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; }}- 注册过滤器
@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(); }}- 修改文件配置,我们通过RouteLocatorBuilder创建路由规则,所以在配置文件中我们不需要再增加路由规则,如下配置
server: port: 8892spring: application: name: gateway-server- 测试,自定义过滤器被执行

实现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类继承关系

在类继承关系中,比较重要的有四个类
- 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自定义网关过滤器
下面简单的介绍一下如何自定义网关过滤器。实现有三步步骤,如下所示
- 修改配置文件
spring: profiles: customFilter cloud: gateway: routes: - id: product-service # 路由ID 唯一 uri: http://localhost:8890 # 目标URL,路由到对应的微服务地址 predicates: - Path=/product/** # 匹配对应URL请求,将匹配的请求追加到目标URI之后 filters: - RequestLog=test1,test2- 实现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类
- 测试调用http://localhost:8892/product/1?test=测试自定义网关过滤器

自定义全局过滤器
自定义全局过滤器需要实现以下两个接口:GlobalFilter,Ordered,通过全局过滤器可以实现权限校验,安全性验证等功能。
- 定义全局过滤器,并将该类注册到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; }}- 测试

如果有哪里写得不对的,还请各位小友指正,只有不断试错,才能慢慢提高。如果你觉得对你有帮助,请点赞+关注,谢谢!!!!!!
想要源码的小伙伴,可以点击关注,私信!!!
本文详细介绍了如何在Spring Cloud Gateway中自定义网关过滤器和全局过滤器。通过实现GatewayFilter接口和GatewayFilterFactory接口,以及利用AbstractGatewayFilterFactory抽象类,展示了自定义过滤器的实现过程。同时,文章还提到了自定义全局过滤器需要实现GlobalFilter和Ordered接口,用于实现如权限校验等高级功能。
2790

被折叠的 条评论
为什么被折叠?



