全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一化处理的业务需求,比如权限认证,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. 【大数据】SparkSql 连接查询中的谓词下推处理 (一)

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/YPN85WBNcnhk8xKjTPTa2g 作者:李勇 目录: 1.SparkSql 2.连接查询和 ...

  2. 什么是IDE(集成开发环境)?

    实际开发中,除了编译器是必须的工具,我们往往还需要很多其他辅助软件,例如: 编辑器:用来编写代码,并且给代码着色,以方便阅读: 代码提示器:输入部分代码,即可提示全部代码,加速代码的编写过程: 调试器 ...

  3. skeleton在心意web上的实践

    通过手动编写skeleton,在fetch数据时显示skeleton loading,数据拉取成功隐藏skeleton 先看下效果图 在component下创建页面对应的skeleton,然后通过在i ...

  4. python 错误、调试、单元测试、文档测试

    错误分为程序的错误和由用户错误的输入引起的错误,此外还有因为各种各样意外的情况导致的错误,比如在磁盘满的时候写入.从网络爬取东西的时候,网络断了.这类错误称为异常 错误处理 参考链接:https:// ...

  5. Java基础—实现多线程的三种方法

    Java虚拟机(JVM,是运行所有Java程序的抽象计算机,是Java语言的运行环境)允许应用程序并发地运行多个线程.在Java语言中,多线程的实现一般有以下三种方法: 1.实现Runnable接口, ...

  6. Electron使用时拦截HTTP请求的解决方案

    背景 最近在做一个Web和Electron共用一份代码的工程,由于使用到了第三方的库(我们是在线地图),该库的认证方式是请求时加key,并且它在后台会校验referer. 于是问题就来了,Electr ...

  7. HDFS常用API操作 和 HDFS的I/O流操作

    前置操作 创建maven工程,修改pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xs ...

  8. net core 2 读取appsettings.json

    问: .Net Core: Application startup exception: System.IO.FileNotFoundException: The configuration file ...

  9. 其他综合-CentOS 7 使用二进制包搭建lnmp平台

    CentOS 7 使用二进制包搭建lnmp平台 1.实验描述 通过二进制搭建 lnmp 平台,实现 web 环境基本部署 2.实验环境 虚拟机: 系统:CenOS 7.6 内存:2 G+ 数量:1台 ...

  10. C++学习03_引用

    基本使用 C++提供了给变量命名的机制,就是引用(Reference).引用是一种复合类型. //语法 数据类型 &name=data 注意,引用在定义时需要添加&,在使用时不能添加& ...