SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter

这篇具有很好参考价值的文章主要介绍了SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Predicate(断言)

​ Predicate(断言),用于进行判断,如果返回为真,才会路由到具体服务。SpirnngCloudGateway由路由断言工厂实现,直接配置即生效,当然也支持自定义路由断言工厂。

内置路由断言工厂实现

​ SpringCloudGateway路由断言工厂实现有很多,可以帮助开发者完成不同的功能。

  • AfterRoutePredicateFactory:设定日期参数,允许在指定日期时间之后的请求通过
- After=2020-01-20T17:42:47.789+08:00[Asia/Shanghai]
  • BeforeRoutePredicateFactory:设定日期参数,允许在指定日期时间之前的请求通过
- Before=2020-01-20T17:42:47.789+08:00[Asia/Shanghai]
  • BetweenRoutePredicateFactory:设定日期区间,使用逗号分隔,表示允许在时间段内的请求通过
- Between=2020-01-20T17:42:47.789+08:00[Asia/Shanghai],2023-02-20T17:42:47.789+08:00[Asia/Shanghai]
  • CookieRoutePredicateFactory:设置Cookie的名称和cookie值的正则表达式,判断请求是否含有该Cookie名称且值与正则表达式相匹配
- Cookie=chocolate, ch.p
  • HeaderRoutePredicateFactory:设定请求头名称和请求头值的正则表达式,判断请求是否含有该请求头,且值与正则相匹配
- Header=X-Request-Id, \d+
  • HostRoutePredicateFactory:设定host,判断请求的host是否满足条件。
- Host=**.test.com
  • MethodRoutePredicateFactory:设定请求方式,只允许满足请求类型的请求方式通过
- Method=GET
  • PathRoutePredicateFactory:设定路由规则,判断请求地址是否满足设定的路径规则
- Path=/shop/**
  • QueryRoutePredicateFactory:设定参数名称和参数值的正则,判断请求是否含有该参数,且值符合正则规则
- Query=name,z.
  • RemoteAddrRoutePredicateFactory:设置IP地址段,判断请求的主机地址是否满足条件
- RemoteAddr=10.xxx.xxx.xxx/24

注意:这里是一个IP的地址段,不是单纯的IP地址

  • WeightRoutePredicateFactory:设定权重分组和权重值,同一个分组名的路由根据权重值进行转发
routes:
  - id: user_group1
  	uri: http://test1.com
  	predicates:
  		- Path=/user/**
  		- Weight=user_grp,8		# 设置user_grp组,80%请求进入user_group1
  - id: user_group2
  	uri: http://test2.com
  	predicates:
  		- Path=/user/**
  		- Weight=user_grp,2		# 设置user_grp组,20%请求进入user_group2

内置断言实例

指定POST请求

server:
  port: 8083

spring:
  application:
    name: gateway   # 服务名

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 路由,可配置多个
      - id: user_route  # 路由id,唯一即可,默认UUID
        uri: lb://user  # 路由地址(匹配成功后的服务地址) user是用户服务的服务名称
        order: 1  # 路由优先级,默认0,越低优先级越高
        predicates:
        - Path=/user/**   # 断言,匹配规则
        - Method=POST     # 表示需要POST请求

使用CMD测试下:当使用GET请求时,gateway直接打回,告知沒有找到

curl localhost:8083/user/findById?id=1
{"timestamp":"2023-08-26T00:24:35.884+00:00","path":"/user/findById","status":404,"error":"Not Found","message":null,"requestId":"0c70f6cf-1"}

使用POST请求,正确访问(-X POST表示使用POST请求方式)

curl -X POST  localhost:8083/user/findById?id=1
Zhangsan

不指定为POST请求时,请求会被404.

使用Query路由断言

使用Query路由断言工厂,且设置参数名为id,正则表达式\d+(一个或多个数字)

server:
  port: 8083

spring:
  application:
    name: gateway   # 服务名

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 路由,可配置多个
      - id: user_route  # 路由id,唯一即可,默认UUID
        uri: lb://user  # 路由地址(匹配成功后的服务地址) user是用户服务的服务名称
        order: 1  # 路由优先级,默认0,越低优先级越高
        predicates:
        - Path=/user/**   # 断言,匹配规则
        - Query=id, \d+   # 参数名id,且值是数字(一位或多位)

使用cmd调用测试,使用非数字时,被告知404

curl localhost:8083/user/findById?id=ss
{"timestamp":"2023-08-26T00:29:38.252+00:00","path":"/user/findById","status":404,"error":"Not Found","message":null,"requestId":"bc0fe260-3"}

使用数字,符合正则,正确访问

curl localhost:8083/user/findById?id=1
Zhangsan

自定义路由断言工厂

​ 在实际的项目开发中,开发者也可以创建自定义的路由断言工厂,进行自己的业务扩展。实际上前面所有的断言工厂都是继承自AbstractRoutePredicateFactory,并且配置是-Method时那么类就是MethodRoutePredicateFactory要创建自定义断言工厂,我们也需要集成自此类,然后重写自己的扩展即可。

实例:创建自定义断言工厂,只允许id为1~1000的请求通过

  • 编写自定义的断言工厂CustomRoutePredicateFactory,那么配置时就是-Custom
@Component  // 交给Spring管理
public class CustomRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomRoutePredicateFactory.Config> {

    public static final String[] KEY_ARRAY = {"minId", "maxId"};    // 对象属性

    public CustomRoutePredicateFactory() {        // 构造函数,需要给父类初始化一个配置类
        super(CustomRoutePredicateFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(KEY_ARRAY);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {

        return new GatewayPredicate() { // 设置断言逻辑
            @Override
            public String toString() {
                return String.format("minId:%d, maxId:%d", config.getMinId(), config.getMaxId());
            }

            @Override
            public boolean test(ServerWebExchange exchange) {

                // 得到id
                String id = exchange.getRequest().getQueryParams().getFirst("id");

                if (id != null) {
                    int numberId = Integer.parseInt(id);
                    // 当 请求的id是在此范围内,返回true
                    return numberId >= config.getMinId() && numberId <= config.getMaxId();
                }


                return false;
            }
        };
    }
    @Validated
    public static class Config {   // 配置类(注意这里是静态类,否则属性是注入不进去的)

        private Integer minId;  // 最小id
        private Integer maxId;  // 最大id

        public Integer getMinId() {
            return minId;
        }

        public void setMinId(Integer minId) {
            this.minId = minId;
        }

        public Integer getMaxId() {
            return maxId;
        }

        public void setMaxId(Integer maxId) {
            this.maxId = maxId;
        }
    }
}

yml配置

server:
  port: 8083

spring:
  application:
    name: gateway   # 服务名

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 路由,可配置多个
      - id: user_route  # 路由id,唯一即可,默认UUID
        uri: lb://user  # 路由地址(匹配成功后的服务地址) user是用户服务的服务名称
        order: 1  # 路由优先级,默认0,越低优先级越高
        predicates:
        - Path=/user/**   # 断言,匹配规则
        - Custom=1,1000   # 设置值为1,1000

测试,当id不在范围内

curl localhost:8083/user/findById?id=0
{"timestamp":"2023-08-26T01:09:02.567+00:00","path":"/user/findById","status":404,"error":"Not Found","message":null,"requestId":"61dcf9de-1"}

在范围内

curl localhost:8083/user/findById?id=1
Zhangsan

没问题!~

Filter过滤器

​ 做过J2EE开发的应该不会对这个词感到陌生。在SpringCloudGateway中的过滤器也有类似的功能,都可以在请求和响应间做一些自定义的逻辑。

​ Gateway的过滤器又分为局部全局,而且同样有内置和自定义。

内置局部过滤器

局部过滤器只针对当前路由的

  • AddRequestHeader:设定Header的值,为原始的请求添加Header
- AddRequestHeader=X-Request-token, 123456
  • AddRequestParameter:设定参数名和值,为原始请求添加参数
- AddRequestParameter=name, zhangsan
  • AddResponseHeader:设定Header的值,为响应添加Header
- AddResponseHeader=token, 123456
  • DedupeResponseHeader:设定去重的Header名称和去重策略,删除响应头中的重复值
- DedupeResponseHeader=Access-Control-Allow-Credentinals Access-Control-Allow-Origin

多个Header使用空格分隔,去重策略:RETAIN_FIRST(保留第一个)RETAIN_LAST(保留最后一个)RETAIN_UNIQUE(保留所有的唯一值)

  • PrefixPath:给请求加前缀,为原始请求添加路径
- PrefixPath=/userPrefix
  • RedirectTo:设定HTTP状态码和URL,将原始请求重定向到指定的URL
- RedirectTo=302, https://test.com
  • RewritePath:设定原始路径(支持正则)和重写路径(支持正则),重写原始路径
- RewritePath=/user/findById, /user/test
  • StripPrefix:设定要拦截的路径数量,用于修改原始路
- StripPrefix=1	# 如果请求是 /user/findById,那么会被拦截为 /findById
  • RequestSize:设定请求包大小(单位字节,默认5MB)
filters:
	- name: RequestSize
	  args:
	  	maxSize: 5000000

自定义局部过滤器

还是按照前面提到的,id在1~1000内允许访问,否则直接拒绝。同路由断言工厂类似,是配置+GatewayFilterFactory的命名然后继承AbstractGatewayFilterFactory

写一个UserGatewayFilterFactory的类

@Component
public class UserGatewayFilterFactory extends AbstractGatewayFilterFactory<UserGatewayFilterFactory.Config> {

    private static final String[] KEY_ARRAYS = {"minId", "maxId"};

    public UserGatewayFilterFactory() { // 构造函数
        super(UserGatewayFilterFactory.Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {

            // 获取id 
            String id = exchange.getRequest().getQueryParams().getFirst("id");
            if (id != null) {
                int number = Integer.parseInt(id);
                if (number >= config.getMinId() && number <= config.getMaxId()) {
                    // 放行
					return chain.filter(exchange);
                }
            }
            byte[] bytes = ("您不能访问"+id+"用户的数据").getBytes(StandardCharsets.UTF_8);
            DataBuffer wrap = exchange.getResponse().bufferFactory().wrap(bytes);
            // 设定HTTP状态码
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            // 返回友好提示
            return exchange.getResponse().writeWith(Flux.just(wrap));
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(KEY_ARRAYS);
    }

    public static class Config {

        private Integer minId;
        private Integer maxId;

        public Integer getMinId() {
            return minId;
        }

        public void setMinId(Integer minId) {
            this.minId = minId;
        }

        public Integer getMaxId() {
            return maxId;
        }

        public void setMaxId(Integer maxId) {
            this.maxId = maxId;
        }
    }
}

yml配置

server:
  port: 8083

spring:
  application:
    name: gateway   # 服务名

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 路由,可配置多个
      - id: user_route  # 路由id,唯一即可,默认UUID
        uri: lb://user  # 路由地址(匹配成功后的服务地址) user是用户服务的服务名称
        order: 1  # 路由优先级,默认0,越低优先级越高
        predicates:
        - Path=/user/**   # 断言,匹配规则
        filters:
        - User=1,1000		# 设置id为1~1000的过滤

测试一手,id空或id并不在范围内

curl localhost:8083/user/findById
您不能访问null用户的数据

curl localhost:8083/user/findById?id=2000
您不能访问2000用户的数据

成功测试

curl localhost:8083/user/findById?id=1
Zhangsan

全局过滤器

全局过滤器在前面的文章中也大概了解过几个,如openFeign的超时时间等,其他的也基本类似,用的不是很多。

通常情况下自定义全局过滤器是比较常用的了,下面看一个案例,客户端访问时的token认证功能的。

处理类需要实现GlobalFilter和Ordered接口,重写方法

@Component
public class TokenFilter implements GlobalFilter, Ordered { // 自定义全局过滤

    private final static String token = "123456";   // 这里做个模拟token

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        // 从请求头中拿到token
        String token = exchange.getRequest().getHeaders().getFirst("token");
        if (token != null) {
            if (token.equals(TokenFilter.token)) {  // 如果请求头中带的token是123456 那么放行
                // 放行
                return chain.filter(exchange);
            }
        }
        byte[] bytes = ("您不能访问" + exchange.getRequest().getPath() + "地址").getBytes(StandardCharsets.UTF_8);
        DataBuffer wrap = exchange.getResponse().bufferFactory().wrap(bytes);
        exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
        // 返回友好提示
        return exchange.getResponse().writeWith(Flux.just(wrap));
    }

    @Override
    public int getOrder() { // 排序,值越小,优先级越高(说的是过滤器的优先级,当有多个过滤器时,order可以控制它们的执行优先级)
        return 0;
    }
}

下面用工具测试一下,token

SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter,SpringCloud,SpringBoot,Java,gateway,springcloud
SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter,SpringCloud,SpringBoot,Java,gateway,springcloud文章来源地址https://www.toymoban.com/news/detail-691320.html

到了这里,关于SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloudAlibaba Gateway(一)简单集成

    随着服务模块的增加,一定会产生多个接口地址,那么客户端调用多个接口只能使用多个地址,维护多个地址是很不方便的,这个时候就需要统一服务地址。同时也可以进行统一认证鉴权的需求。那么服务网关就充当这样的角色。 Gateway ​ 网关为众多微服务挡在前面,做路由

    2024年02月10日
    浏览(37)
  • 【微服务 SpringCloudAlibaba】实用篇 · Gateway服务网关

    微服务(8) Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 Gateway网关是我们服务的守门神,所有微服务的统一入口

    2024年02月01日
    浏览(40)
  • flinksql 流表转换, 自定义udf/udtf,SQL 内置函数及自定义函数

    1、在大多数情况下,用户定义的函数必须先注册,然后才能在查询中使用。不需要专门为 Scala 的 Table API 注册函数。 2、函数通过调用 registerFunction()方法在 TableEnvironment 中注册。当用户定义的函数 被注册时,它被插入到 TableEnvironment 的函数目录中, 这样 Table API 或 SQL 解

    2024年02月22日
    浏览(51)
  • SpringCloudAlibaba:服务网关之Gateway的cors跨域问题

    目录 一:解决问题 二:什么是跨域 三:cors跨域是什么?  遇到错误:         前端请求时报错 解决: 网关中添加配置文件, 注意springboot版本 ,添加配置。 跨域是指浏览器处于安全考虑,对 JavaScript 发起的不同源的请求进行限制的一种机制。 所谓同源是指协议,域名和

    2024年02月15日
    浏览(41)
  • SpringCloudGateway--过滤器(内置filter)

    目录 一、概览 二、内置过滤器 1、StripPrefix 2、AddRequestHeader 3、AddResponseHeader 4、DedupeResponseHeader 5、AddRequestParameter 6、CircuitBreaker 7、FallbackHeaders 8、RequestRateLimiter 9、RedirectTo 10、RemoveRequestHeader 11、RemoveResponseHeader 12、RemoveRequestParameter 13、RewritePath  14、RewriteResponseHeader  15、S

    2024年02月01日
    浏览(55)
  • SpringCloudAlibaba Gateway(三)-整合Sentinel功能路由维度、API维度进行流控

    ​ 前面使用过Sentinel组件对服务提供者、服务消费者进行流控、限流等操作。除此之外,Sentinel还支持对Gateway、Zuul等主流网关进行限流。 ​ 自sentinel1.6.0版开始,Sentinel提供了Gateway的适配模块,能针对路由(route)和自定义API分组两个维度进行限流。 路由维度是指配置文件中的

    2024年02月10日
    浏览(33)
  • SpringCloud GateWay-Filter学习

    路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应 Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生 开发直接使用 GatewayFilter 较少,一般是自定义过滤器 第一步、修改e-commerce-gateway-20000 中的 application.yml 第二步、验证、修改member-service-provider-

    2024年02月08日
    浏览(30)
  • springcloud3 GateWay章节-Nacos+gateway(跨域,filter过滤等5

    1.验证制定请求,是否可以通过。 1.4.1 异常定义 1.异常配置类 2.异常响应类 1.4.2 测试 1.将调用的微服务都关闭,只保留网关服务。 http://localhost:7004/payment/nacos/222  

    2024年02月11日
    浏览(38)
  • 云原生之 Gateway 的 Filter 过滤器

    通常情况下,出于安全方面的考虑, 服务端提供的服务往往都会有一定的校验逻辑 ,例如用户登陆状态校验、签名校验等。 在微服务架构中,系统由多个微服务组成,所有这些服务都需要这些校验逻辑,此时我们就可以将 这些校验逻辑写到 Spring Cloud Gateway 的 Filter 过滤器中

    2023年04月14日
    浏览(50)
  • 44、Flink之module模块介绍及使用示例和Flink SQL使用hive内置函数及自定义函数详细示例--网上有些说法好像是错误的

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包