springc...

Gateway使用自定义Filter

2021-07-12  本文已影响0人  文景大大

虽然Gateway给我们提供了丰富的内置Filter,但是实际项目中,自定义FIlter的场景非常常见,因此单独介绍下自定义FIlter的使用。

一、使用GatewayFilter

首先自建一个LogFilter,并实现GatewayFilter接口和Ordered接口。

public class LogFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 前置过滤器
        System.out.println("LogFilter filtered!--PRE");
        return chain.filter(exchange).then(
            Mono.fromRunnable(() -> {
                // 后置过滤器
                System.out.println("LogFilter filtered!--POST");
            }
                             ));
    }

    /**
     * 设定过滤器的优先级,值越小则优先级越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

这个过滤器中分为前置过滤器和后置过滤器,然后我们在启动类中注册这个Filter即可。

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        return builder.routes()
            .route("blog_route",r -> r.path("/zhangxun")
                   .filters(f -> f.filters(new LogFilter()))
                   .uri("https://blog.csdn.net"))
            .build();
    }

}

如此,启动项目后,我们LogFilter就能正常工作了。

二、使用过滤器工厂

上述方式定义Filter的话,我们无法在配置文件中来配置过滤器,只能在Bean中进行绑定Filter,会显得比较繁琐。如果能在配置文件中进行配置就很方便了,那么使用过滤器工厂就是这样的方式。

我们手下新建一个LogFilter2的过滤器,并继承过滤器工厂:

@Component
public class LogFilter2 extends AbstractGatewayFilterFactory {
    @Override
    public GatewayFilter apply(Object config) {
        return (exchange,chain) -> {
            System.out.println("LogFilter2 flitered!!!");
            return chain.filter(exchange);
        };
    }
}

这个过滤器就只是打印一行日志,然后我们在配置文件中启用如下的配置:

spring:
  application:
    name: gateway-demo-service
  cloud:
    gateway:
      routes:
        - id: blog_route
          uri: https://blog.csdn.net
          predicates:
            - Path=/zhangxun
          filters:
            - StripPrefix=1
            - LogFilter2

在filters中指定需要使用的过滤器即可,非常简单,再次重启应用,就能使得/zhangxun的请求出发我们的LogFilter2过滤器了。

三、实现全局Filter

方式一

全局Filter的使用比较简单,不需要配置。我们新建一个全局的FIlter:

@Component
public class GlobalLogFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 前置过滤器
        System.out.println("GlobalLogFilter filtered!--PRE");
        return chain.filter(exchange).then(
            Mono.fromRunnable(() -> {
                // 后置过滤器
                System.out.println("GlobalLogFilter filtered!--POST");
            }
                             ));
    }

    /**
 * 设定过滤器的优先级,值越小则优先级越高
 *
 * @return
 */
    @Override
    public int getOrder() {
        return 0;
    }
}

然后就可以直接启动项目了,这里和GateWayFilter唯一不同的就是实现的GlobalFilter。对于任意请求都能进行拦截处理。

注意:全局Filter的pre处理优先于局部处理器的pre,全局Filter的post处理落后于局部处理器的post;

GlobalLogFilter filtered!--PRE
LogFilter filtered!--PRE
LogFilter filtered!--POST
GlobalLogFilter filtered!--POST

方式二

还有一种方式不需要使用GlobalFilter,而是使用过滤器工厂,然后我们在配置文件中设置defaultFilter即可。

例子使用第二章节的代码,我们配置文件改为如下:

spring:
  application:
    name: gateway-demo-service
  cloud:
    gateway:
      default-filters:
        - LogFilter2
      routes:
        - id: blog_route
          uri: https://blog.csdn.net
          predicates:
            - Path=/zhangxun
          filters:
            - StripPrefix=1

那么此时,我们设置了默认的Filter,在访问任意请求时,都可以出发LogFilter2的过滤器。

上一篇下一篇

猜你喜欢

热点阅读