全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一化处理的业务需求,比如权限认证,IP访问限制等等。

接口定义类:org.springframework.cloud.gateway.filter.GlobalFilter

public interface GlobalFilter {
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

gateway自带的GlobalFilter实现类有很多,如下图:

有转发,路由,负载等相关的GlobalFilter,感兴趣的可以自己去看下源码,了解下。

我们自己如何定义GlobalFilter来实现我们自己的业务逻辑?

给出一个官方文档上的案例:

@Configuration
public class ExampleConfiguration {
private Logger log = LoggerFactory.getLogger(ExampleConfiguration.class); @Bean
@Order(-1)
public GlobalFilter a() {
return (exchange, chain) -> {
log.info("first pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("third post filter");
}));
};
} @Bean
@Order(0)
public GlobalFilter b() {
return (exchange, chain) -> {
log.info("second pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("second post filter");
}));
};
} @Bean
@Order(1)
public GlobalFilter c() {
return (exchange, chain) -> {
log.info("third pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("first post filter");
}));
};
}
}

上面定义了3个GlobalFilter,通过@Order来指定执行的顺序,数字越小,优先级越高。下面就是输出的日志,从日志就可以看出执行的顺序:

2018-10-14 12:08:52.406  INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration  : first pre filter
2018-10-14 12:08:52.406 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : second pre filter
2018-10-14 12:08:52.407 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : third pre filter
2018-10-14 12:08:52.437 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : first post filter
2018-10-14 12:08:52.438 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : second post filter
2018-10-14 12:08:52.438 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : third post filter

当GlobalFilter的逻辑比较多时,我还是推荐大家单独写一个GlobalFilter来处理,比如我们要实现对IP的访问限制,不在IP白名单中就不让调用的需求。

单独定义只需要实现GlobalFilter, Ordered这两个接口就可以了。

@Component
public class IPCheckFilter implements GlobalFilter, Ordered { @Override
public int getOrder() {
return 0;
} @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
HttpHeaders headers = exchange.getRequest().getHeaders();
// 此处写死了,演示用,实际中需要采取配置的方式
if (getIp(headers).equals("127.0.0.1")) {
ServerHttpResponse response = exchange.getResponse();
ResponseData data = new ResponseData();
data.setCode(401);
data.setMessage("非法请求");
byte[] datas = JsonUtils.toJson(data).getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(datas);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
return chain.filter(exchange);
} // 这边从请求头中获取用户的实际IP,根据Nginx转发的请求头获取
private String getIp(HttpHeaders headers) {
return "127.0.0.1";
} }

过滤的使用没什么好讲的,都比较简单,作用却很大,可以处理很多需求,上面讲的IP认证拦截只是冰山一角,更多的功能需要我们自己基于过滤器去实现。

比如我想做a/b测试,那么就得在路由转发层面做文章,前面我们有贴一个图片,图片中有很多默认的全局过滤器,其中有一个LoadBalancerClientFilter是负责选择路由服务的负载过滤器,里面会通过loadBalancer去选择转发的服务,然后传递到下面的路由NettyRoutingFilter过滤器去执行,那么我们就可以基于这个机制来实现。

Filter中往下一个Filter中传递数据实用下面的方式:

exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);

获取方直接获取:

URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);

如果我想改变路由的话,就可以这样做:

@Component
public class DebugFilter implements GlobalFilter, Ordered { @Override
public int getOrder() {
return 10101;
} @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
try {
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, new URI("http://192.168.31.245:8081/house/hello2"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
return chain.filter(exchange);
} }

LoadBalancerClientFilter的order是10100,我们这边比它大1,这样就能在它执行完之后来替换要路由的地址了。

欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

spring cloud gateway 全局过滤器的更多相关文章

  1. spring cloud gateway自定义过滤器

    在API网关spring cloud gateway和负载均衡框架ribbon实战文章中,主要实现网关与负载均衡等基本功能,详见代码.本节内容将继续围绕此代码展开,主要讲解spring cloud g ...

  2. Spring Cloud Gateway自定义过滤器实战(观测断路器状态变化)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. Spring Cloud Alibaba学习笔记(19) - Spring Cloud Gateway 自定义过滤器工厂

    在前文中,我们介绍了Spring Cloud Gateway内置了一系列的内置过滤器工厂,若Spring Cloud Gateway内置的过滤器工厂无法满足我们的业务需求,那么此时就需要自定义自己的过 ...

  4. Spring Cloud Gateway 全局通用异常处理

    为什么需要全局异常处理 在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回 // 摘至 spring cloud alibaba c ...

  5. 微服务网关实战——Spring Cloud Gateway

    导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...

  6. 微服务网关 Spring Cloud Gateway

    1.  为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...

  7. spring cloud gateway获取response body

    网关发起请求后,微服务返回的response的值要经过网关才发给客户端.本文主要讲解在spring cloud gateway 的过滤器中获取微服务的返回值,因为很多情况我们需要对这个返回进行处理.网 ...

  8. 快速突击 Spring Cloud Gateway

    认识 Spring Cloud Gateway Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 构建的 API ...

  9. Spring Cloud Gateway 实现Token校验

    在我看来,在某些场景下,网关就像是一个公共方法,把项目中的都要用到的一些功能提出来,抽象成一个服务.比如,我们可以在业务网关上做日志收集.Token校验等等,当然这么理解很狭隘,因为网关的能力远不止如 ...

随机推荐

  1. windows下mysql安装和配置

    历史版本下载地址安装,解压添加环境变量使用cmd中操作mysql进程修改mysql的配置附录:设置mysql随开机自启 TOC 历史版本下载地址 windows的mysql历史版本,推荐使用5.6版本 ...

  2. vue 移动端上传图片结合localResizeIMG插件进行图片压缩

    localResizeIMG插件的功能是将图片进行压缩,然后转换成base64传给后台. 首先, npm i lrz -save 然后,再main.js里面引入lrz import lrz from ...

  3. 锁定文件失败,打不开磁盘“D:\biehl\centos\taotao\taotao-dubbo-register\CentOS-000001.vmdk”或它所依赖的某个快照磁盘。模块“Disk”启动失败。未能启动虚拟机

    1.锁定文件失败,打不开磁盘“D:\biehl\centos\taotao\taotao-dubbo-register\CentOS-000001.vmdk”或它所依赖的某个快照磁盘.模块“Disk” ...

  4. 基于SqlClient开发SQLServer工具类 伸手党的福音

    注意:代码直接Copy调用即可,SQLServer工具类跟我上一个Oracle工具类有所不同,区别在于调用存储过程中时参数的使用,无需输入对应的存储游标名称 特点:根据用户传入的参数类型来识别存储中对 ...

  5. WPF两个按钮来回切换样式

    <!-- 两个按钮来回切换样式 --> <Style x:Key="SwicthFunctionMetroToggleButton" TargetType=&qu ...

  6. ORACLE 求和(多列)

    SELECT SUM(列名),SUM(列名),SUM(列名),SUM(列名) FROM 表名

  7. python中pip添加国内镜像源后显著加速下载

    python中pip添加国内镜像源后显著加速下载 更换pip源到国内镜像,很多国外的库下载非常慢,添加国内镜像后安装下载速度提升非常明显(亲测有些可以由几十kb加速到几MB) pip国内的一些镜像阿里 ...

  8. python高级语法1

    1.解压序列赋值给多个变量 p = (4, 5, 6) x, y , z = p # x = 4, y = 5, z = 6 若可迭代对象超过变量个数,会抛出ValueError 用处:可以解压赋值任 ...

  9. IntelliJ IDEA 中使用 Lambok (注解无效问题的解决)

    一,概述 Lambok可以说一个能很大提高开发效率的插件,只要在使用注解的方式就能实现很多常用的功能.如常用的@Data能在编译阶段自动生成toString方法,getter方法setter方法等. ...

  10. 【android】关于call拨号功能实现的记录

    前几天考试居然记错dial和call,故在此写上小demo来作区别,加深印象. 主要是实现call(拨通电话)功能,dial(拨电话)功能用作对比,话不多说,贴上代码. 1.创建布局文件如下: < ...