Spring Cloud Alibaba-05-Gateway网关-02-断言(Predicate)使用

Lison <dreamlison@163.com>, v1.0.0, 2023.10.20

Spring Cloud Alibaba-05-Gateway网关-02-断言(Predicate)使用

文章目录

  • Spring Cloud Alibaba-05-Gateway网关-02-断言(Predicate)使用
    • 通过时间匹配
    • 通过 Cookie 匹配
    • 通过 Header 匹配
    • 通过 Host 匹配
    • 通过请求方式匹配
    • 通过请求路径匹配
    • 通过请求参数匹配
    • 通过请求 ip 地址进行匹配
    • 自定义断言
      • 如何自定义路由断言
      • 实现
    • 组合使用

Predicate 断言,用于进行条件判断,只有断言都为真,才会真正的执行路由。

通过时间匹配

Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。比如我们现在设置只有在 2023年 10 月 20 日才会转发到我的网站,在这之前不进行转发,我就可以这样配置:

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- After=2023-10-20T08:30:00+08:00[Asia/Shanghai]

Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai。

After Route Predicate 是指在这个时间之后的请求都转发到目标地址。上面的示例是指,请求时间在 2023 年 10 月 20 日 08 点 30 分 0 秒之后的所有请求都转发到地址http://localhost:18001。+08:00是指时间和 UTC 时间相差八个小时,时间地区为Asia/Shanghai。

添加完路由规则之后,访问地址http://localhost:18001/spring_service 会自动转发到http://localhost:18001。

Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发。我们把上面路由规则中的 After 改为 Before,如下:

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Before=2023-10-20T08:30:00+08:00[Asia/Shanghai]

就表示在这个时间之前可以进行路由,在这时间之后停止路由,修改完之后重启项目再次访问地址http://localhost:18001/spring_service ,页面会报 404 没有找到地址。

除过在时间之前或者之后外,Gateway 还支持限制路由请求在某一个时间段范围内,可以使用 Between Route Predicate 来实现

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Between=2023-10-20T08:30:00+08:00[Asia/Shanghai],2024-10-20T08:30:00+08:00[Asia/Shanghai]

这样设置就意味着在这个时间段内可以匹配到此路由,超过这个时间段范围则不会进行匹配。通过时间匹配路由的功能很酷,可以用在限时抢购的一些场景中。

通过 Cookie 匹配

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Cookie=token,lison

在这里插入图片描述
在这里插入图片描述

总结:去掉Cookie或Cookie不正确,后台汇报 404 错误。带上正确的Cookie正常访问

通过 Header 匹配

Header Route Predicate 和 Cookie Route Predicate 一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Header=X-Request-Id, \d+

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

总结:去掉Header或Header不合法,后台汇报 404 错误。带上合法的Header正常访问

通过 Host 匹配

Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Host=**.lison.com

在这里插入图片描述

经测试以上两种 host 均可匹配到 host_route 路由,去掉 host 参数则会报 404 错误。

通过请求方式匹配

可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Method=GET

测试返回页面代码,证明匹配到路由,我们再以 POST 的方式请求测试。返回 404 没有找到,证明没有匹配上路由

通过请求路径匹配

Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Path=/spring_service/{segment} # - Path=/spring_service/**

如果请求路径符合要求,则此路由将匹配,例如:/spring_service/1 或者 /spring_service/bar。

测试:

http://localhost:18003/spring_service/1
http://localhost:18003/spring_service/2
http://localhost:18003/spring_xxx/2

经过测试第一和第二条命令可以正常获取到页面返回值,最后一个命令报 404,证明路由是通过指定路由来匹配。

通过请求参数匹配

Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Query=token

这样配置,只要请求中包含 token 属性的参数即可匹配路由。

http://localhost:18003/spring_service/getServerProd?token=dfasdfas&id=xxx

经过测试发现只要请求汇总带有 smile 参数即会匹配路由,不带 token 参数则不会匹配。

还可以将 Query 的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Query=token,lison.

这样只要当请求中包含 keep 属性并且参数值是以 lison 开头的长度为六位的字符串才会进行匹配和路由。

http://localhost:18003/spring_service/getServerProd?token=lison6&id=xxx

测试可以返回页面代码,将 token 的属性值改为 pubx 再次访问就会报 lison66, 证明路由需要匹配正则表达式才会进行路由。

通过请求 ip 地址进行匹配

Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号 (IPv4 或 IPv6) 字符串的列表(最小大小为 1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- RemoteAddr=192.168.1.1/24

可以将此地址设置为本机的 ip 地址进行测试。

如果请求的远程地址是 192.168.1.10,则此路由将匹配。

自定义断言

如何自定义路由断言

我们可以查看内置的断言如何实现?举例:BetweenRoutePredicateFactory

//断言工厂的类的命名规则为XXXXRoutePredicateFactory   需要 继承AbstractRoutePredicateFactorypublic class BetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<Config> {public static final String DATETIME1_KEY = "datetime1";public static final String DATETIME2_KEY = "datetime2";public BetweenRoutePredicateFactory() {super(Config.class);}public List<String> shortcutFieldOrder() {return Arrays.asList("datetime1", "datetime2"); //与配置文件映射}//判断逻辑方法public Predicate<ServerWebExchange> apply(final Config config) {Assert.isTrue(config.getDatetime1().isBefore(config.getDatetime2()), config.getDatetime1() + " must be before " + config.getDatetime2());return new GatewayPredicate() {//核心判断逻辑public boolean test(ServerWebExchange serverWebExchange) {ZonedDateTime now = ZonedDateTime.now();return now.isAfter(config.getDatetime1()) && now.isBefore(config.getDatetime2());}public String toString() {return String.format("Between: %s and %s", config.getDatetime1(), config.getDatetime2());}};}//参数配置类@Validatedpublic static class Config {private @NotNull ZonedDateTime datetime1;private @NotNull ZonedDateTime datetime2;public Config() {}public ZonedDateTime getDatetime1() {return this.datetime1;}public Config setDatetime1(ZonedDateTime datetime1) {this.datetime1 = datetime1;return this;}public ZonedDateTime getDatetime2() {return this.datetime2;}public Config setDatetime2(ZonedDateTime datetime2) {this.datetime2 = datetime2;return this;}}
}

知道内置路由断言的实现细节,我们只需要按照它的实现方式,来按部就班的实现自己的路由断言即可。

实现

需求假设:年龄大于18岁,小于60岁的可以访问

1、先进行路由设置

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Age=18,60 #年龄大于18岁,小于60岁的可以访问

2、自定义实现路由,根据前面的配置我们知道规则名为Age,那么我们的自定义的断言名称必须是AgeRoutePredicateFactory

package com.lison.springcloudservice.config.predicates;/*** @className: com.lison.springcloudservice.config.predicates-> AgeRoutePredicateFactory* @description:   自定义的断言工厂 1.名称必须是配置+RoutePredicateFactory 2.必须继承AbstractRoutePredicateFactory<配置类>* @author: Lison* @createDate: 2023-10-20*/
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {public AgeRoutePredicateFactory() {super(AgeRoutePredicateFactory.Config.class);}//读取配置文件的参数值,赋值到配置类中的属性上@Overridepublic List<String> shortcutFieldOrder() {//顺序必须与yml文件中的配置顺序对应return Arrays.asList("minAge", "maxAge");}@Overridepublic Predicate<ServerWebExchange> apply(AgeRoutePredicateFactory.Config config) {return new Predicate<ServerWebExchange>() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {//serverWebExchange很强大,可以可以获取到很多内容String ageStr = serverWebExchange.getRequest().getQueryParams().getFirst("age");if (StringUtils.isNotEmpty(ageStr)) {int age = Integer.parseInt(ageStr);return age > config.getMinAge() && age < config.getMaxAge();}return false;}};}//用于接收参数public static class Config {private int minAge;private int maxAge;public int getMinAge() {return minAge;}public void setMinAge(int minAge) {this.minAge = minAge;}@Overridepublic String toString() {return "Config{" +"minAge=" + minAge +", maxAge=" + maxAge +'}';}public int getMaxAge() {return maxAge;}public void setMaxAge(int maxAge) {this.maxAge = maxAge;}}
}

3、重启服务网关,测试自定义的路由断言,age=20可以访问,而age=15则无法访问

组合使用

上面为了演示各个 Predicate 的使用,我们是单个单个进行配置测试,其实可以将各种 Predicate 组合起来一起使用。

spring:cloud:gateway:routes:- id: spring_serviceuri: http://localhost:18001predicates:- Host=**.lison.com- Path=/spring_service/** # 当请求路径满足Path指定的规则时,才进行路由转发- Cookie=token,lison- After=2023-10-20T08:30:00+08:00[Asia/Shanghai]- Before=2023-10-20T08:30:00+08:00[Asia/Shanghai]- Between=2023-10-20T08:30:00+08:00[Asia/Shanghai],2024-10-20T08:30:00+08:00[Asia/Shanghai]- Header=X-Request-Id, \d+- Host=**.lison.com- Method=GET,POST- Query=token,lison.- RemoteAddr=192.168.1.1/24- Age=18,60 

各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。

一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/697497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# CAD2016 cass10宗地Xdata数据写入

一、 查看cass10写入信息 C# Cad2016二次开发获取XData信息&#xff08;二&#xff09; 一共有81条数据 XData value: QHDM XData value: 121321 XData value: SOUTH XData value: 300000 XData value: 141121JC10720 XData value: 权利人 XData value: 0702 XData value: YB…

2.居中方式总结

居中方式总结 经典真题 怎么让一个 div 水平垂直居中 盒子居中 首先题目问到了如何进行居中&#xff0c;那么居中肯定分 2 个方向&#xff0c;一个是水平方向&#xff0c;一个是垂直方向。 水平方向居中 水平方向居中很简单&#xff0c;有 2 种常见的方式&#xff1a; 设…

java面试题之mybatis篇

什么是ORM&#xff1f; ORM&#xff08;Object/Relational Mapping&#xff09;即对象关系映射&#xff0c;是一种数据持久化技术。它在对象模型和关系型数据库直接建立起对应关系&#xff0c;并且提供一种机制&#xff0c;通过JavaBean对象去操作数据库表的数据。 MyBatis通过…

MATLAB练习题:randperm函数的练习题

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili MATLAB中有一个非常有用的函数&#xff1a;randperm函数&…

华为算法题 go语言或者ptython

1 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返…

如何进行高性能架构的设计

一、前端优化 减少请求次数页面静态化边缘计算 增加缓存控制&#xff1a;请求头 减少图像请求次数&#xff1a;多张图片变成 一张。 减少脚本的请求次数&#xff1a;css和js压缩&#xff0c;将多个文件压缩成一个文件。 二、页面静态化 三、边缘计算 后端优化 从三个方面进…

adb-monkey命令

目录 adb shell monkey -p/-v 包名 次数 1、指定一个包 2、指定多个包 3、不指定包 Event percentages&#xff08;事件百分比&#xff09; 常见参数 --throttle 延迟时间 单位毫秒 --pct-touch 设定触屏事件生成的百分比 --pct-motion 设定滑动事件生成…

面试前端性能优化八股文十问十答第二期

面试前端性能优化八股文十问十答第二期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;如何优化动画&#x…

c语言中的大小写字母转换怎么转?

在C语言中&#xff0c;大小写字母转换是基于ASCII码表的特性实现的。ASCII码中&#xff0c;小写字母从’a’到’z’的ASCII码值是连续的&#xff08;97到122&#xff09;&#xff0c;而大写字母从’A’到’Z’的ASCII码值也是连续的&#xff08;65到90&#xff09;。它们之间有…

Redis高性能原理

redis大家都知道拥有很高的性能&#xff0c;每秒可以支持上万个请求&#xff0c;这里探讨下它高性能的原理。单线程架构和io多路复用技术。 一&#xff0c;单线程架构 单线程架构指的是命令执行核心线程是单线程的&#xff0c;数据持久化、同步、异步删除是其他线程在跑的。re…

获取视频第一帧,以及后续上传

// 获取视频基本信息 const getVideoBasicInfo (videoSrc) > {return new Promise((resolve, reject) > {const video document.createElement("video");video.src videoSrc;// 视频一定要添加预加载video.preload "auto";// 视频一定要同源或者…

什么是系统工程(字幕)35

0 00:00:01,190 --> 00:00:02,840 下面的内容 1 00:00:04,850 --> 00:00:06,520 接下来呢就是 2 00:00:08,180 --> 00:00:09,830 16.6.1 3 00:00:11,070 --> 00:00:13,440 项流热平衡分析 4 00:00:15,350 --> 00:00:16,730 这一节 5 00:00:18,860 --> 0…

亿道丨三防平板丨加固平板丨三防加固平板丨改善资产管理

库存资产管理中最重要的部分之一是准确性&#xff1b;过时的库存管理技术会增加运输过程中人为错误、物品丢失或纸张损坏的风险。如今随着三防平板电脑的广泛使用&#xff0c;库存管理也迎来了好帮手&#xff0c;通过使用三防平板电脑能够确保库存管理、数据存储和记录保存的准…

React18源码: React调度中的3种优先级类型和Lane的位运算

优先级类型 React内部对于优先级的管理&#xff0c;贯穿运作流程的4个阶段&#xff08;从输入到输出&#xff09;&#xff0c;根据其功能的不同&#xff0c;可以分为3种类型&#xff1a; 1 &#xff09;fiber优先级(LanePriority) 位于 react-reconciler包&#xff0c;也就是L…

掌握 Android 中的 RecyclerView 优化

掌握 Android 中的 RecyclerView 优化 一、RecyclerView Pool以及何时使用它二、onCreateViewHolder 和 onBindViewHolder三、优化 RecyclerView 的不同方法四、视图无效与请求布局五、ViewHolder模式六、默认的废料和脏视图类型七、结论 RecyclerView 是 Android 中一个功能强…

【操作系统】磁盘存储空间的管理

实验5 磁盘存储空间的管理 一、实验目的 磁盘是用户存放程序和数据的存储设备&#xff0c;磁盘管理的主要目的是充分有效地利用磁盘空间。本实验模拟实现磁盘空间的分配与回收&#xff0c;使学生对磁盘空间的管理有一个较深入的理解。 二、实验内容 实验任务&#xff1a;用位…

FreeSWITCH debian11/12 apt安装

官方给的easy way安装方式如下&#xff1a; # 换成自己的token TOKENpat_ZrPXJQ8JNWsVQW2ubhnUwi7gapt-get update && apt-get install -y gnupg2 wget lsb-releasewget --http-usersignalwire --http-password$TOKEN -O /usr/share/keyrings/signalwire-freeswitch-…

#LLM入门|Prompt#1.2_提示原则_Guidelines

提示原则 一、编写清晰、具体的指令 使用分隔符清晰地表示输入的不同部分&#xff1a; 在Prompt中使用分隔符&#xff0c;如、“”"、< >、 、:等&#xff0c;将不同的文本部分区分开来&#xff0c;避免混淆和意外的结果。分隔符能够防止提示词注入&#xff0c;提…

petalinux_zynq7 驱动DAC以及ADC模块之四:python实现http_api

前文&#xff1a; petalinux_zynq7 C语言驱动DAC以及ADC模块之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…

Java观察者模式:实现高效的事件驱动编程

Java中的装饰者模式&#xff1a;灵活地为对象添加功能 一、引言 在软件设计中&#xff0c;我们经常需要为对象动态地添加功能或行为。装饰者模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许我们在运行时将功能动态地添加到对象上&…