1. 序言
基本上gateway自带的过滤器都能满足我们的使用,除了使用自带的,我们也可以自定义过滤器实现自己的逻辑
2. 工程搭建
基本步骤不变,只是在配置环节有不一样
3. 全局过滤器
全局过滤器只需要实现GlobalFilter
即可,所有的请求都会走此过滤器,用于做全局的事件处理,如权限验证、日志记录、租户校验等……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Component public class LogGlobalFilter implements GlobalFilter { private static final Logger logger = LoggerFactory.getLogger(RuntimeException.class); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { StopWatch watch = new StopWatch(); watch.start(); try { return chain.filter(exchange); } catch (RuntimeException e) { logger.error("过滤器中发生异常:"+e.getMessage(),e); throw e; } finally { watch.stop(); logger.info("任务执行时间:"+watch.prettyPrint()); } } }
|
只要LogGlobalFilter
加入容器扫描到即可,框架会自行扫描GlobalFilter
对应的类,然后加入全局过滤器中
4. 局部过滤器
局部过滤器在局部请求中使用,因此需要有创建和配置两个过程
4.1. 创建
创建一个过滤器继承AbstractGatewayFilterFactory
,也可以实现GatewayFilterFactory
,但一般通过继承AbstractGatewayFilterFactory
来处理会方便很多。
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 38 39 40 41 42
| @Component @Slf4j public class ProviderServiceGatewayFilterFactory extends AbstractGatewayFilterFactory<ProviderServiceGatewayFilterFactory.ProviderConfig> {
public ProviderServiceGatewayFilterFactory() { super(ProviderConfig.class); } @Override public GatewayFilter apply(ProviderConfig config) {
log.info("ProviderServiceGatewayFilterFactory apply");
if (config.postLogger){ log.info("postLogger enable"); } if (config.preLogger){ log.info("preLogger enable"); } return new GatewayFilter() { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("ProviderServiceGatewayFilterFactory inner filter"); return chain.filter(exchange); } }; }
@Data public static class ProviderConfig { private String message; private boolean preLogger; private boolean postLogger; } }
|
注意,过滤器工厂命名的时候一定要以GatewayFilterFactory
结尾命名,这是约定大于配置的体现,实现了此则才能使用filters中的如下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| routes: - id: header_route uri: https://example.org predicates: - Header=X-Request-Id, \d+ filters: - ProviderService=message1,true,true - name: ProviderService args: message: message1 preLogger: true postLogger: true
|