spring cloud gateway 全局过滤器
全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一化处理的业务需求,比如权限认证,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 全局过滤器的更多相关文章
- spring cloud gateway自定义过滤器
在API网关spring cloud gateway和负载均衡框架ribbon实战文章中,主要实现网关与负载均衡等基本功能,详见代码.本节内容将继续围绕此代码展开,主要讲解spring cloud g ...
- Spring Cloud Gateway自定义过滤器实战(观测断路器状态变化)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Spring Cloud Alibaba学习笔记(19) - Spring Cloud Gateway 自定义过滤器工厂
在前文中,我们介绍了Spring Cloud Gateway内置了一系列的内置过滤器工厂,若Spring Cloud Gateway内置的过滤器工厂无法满足我们的业务需求,那么此时就需要自定义自己的过 ...
- Spring Cloud Gateway 全局通用异常处理
为什么需要全局异常处理 在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回 // 摘至 spring cloud alibaba c ...
- 微服务网关实战——Spring Cloud Gateway
导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...
- 微服务网关 Spring Cloud Gateway
1. 为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...
- spring cloud gateway获取response body
网关发起请求后,微服务返回的response的值要经过网关才发给客户端.本文主要讲解在spring cloud gateway 的过滤器中获取微服务的返回值,因为很多情况我们需要对这个返回进行处理.网 ...
- 快速突击 Spring Cloud Gateway
认识 Spring Cloud Gateway Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 构建的 API ...
- Spring Cloud Gateway 实现Token校验
在我看来,在某些场景下,网关就像是一个公共方法,把项目中的都要用到的一些功能提出来,抽象成一个服务.比如,我们可以在业务网关上做日志收集.Token校验等等,当然这么理解很狭隘,因为网关的能力远不止如 ...
随机推荐
- 【洛谷5438】【XR-2】记忆(数论)
[洛谷5438][XR-2]记忆(数论) 题面 洛谷 题解 很好的一道题目. 我们首先把所有数的每个质因子的出现次数模二,也就是把最大的完全平方因子给除掉.然后剩下部分一样的就可以产生\(1\)的贡献 ...
- Git在提交代码时出现的fatal: Authentication failed的问题
git push origin master remote: Incorrect username or password ( access token ) fatal: Authentication ...
- JavaScript的闭包特性如何给循环中的对象添加事件(一)
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
- sql server 查看连接详情
SELECT * FROM [Master].[dbo].[SYSPROCESSES] WHERE [DBID] IN ( SELECT [DBID] FROM [Master].[dbo].[SYS ...
- jmeter返回结果出现乱码
这是我的问题: 请求的百度地址,返回的数据是中文乱码 去jmeter安装目录的bin下: 修改配置文件jmeter.properties 右键打开 ,查找:sampleresult.default.e ...
- Java学习——枚举类
Java学习——枚举类 摘要:本文主要介绍了Java的枚举类. 部分内容来自以下博客: https://www.cnblogs.com/sister/p/4700702.html https://bl ...
- Java自学-集合框架 HashMap
Java集合框架 HashMap 示例 1 : HashMap的键值对 HashMap储存数据的方式是-- 键值对 package collection; import java.util.HashM ...
- Expression表达式目录树动态拼接 反射获取泛型方法
class TestOne { public String[] arr = { "1", "2", "3" }; public class ...
- 深入浅出《设计模式》之工厂模式(C++)
前言 模式介绍 在之前简单工厂模式中,我们介绍了简单工厂模式的缺陷是违背了开放-封闭原则.如果在面馆中添加了烤海参,那将会修改waiter工厂类.违背了类内封闭原则. 还以面馆为例,现在两种面,用一个 ...
- 模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径
模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...