虽然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的过滤器。
网友评论