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…

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 设定滑动事件生成…

Redis高性能原理

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

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

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

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

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

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

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

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…

串的相关题目

于是他错误的点名开始了 我发现有关hash得题目有些是可以通过map数组来完成的&#xff1a;何为map数组&#xff0c;我们先思考一下最简单的桶的排序&#xff0c;桶排序是将我们需要数字最为下标输进数组中&#xff0c;而数组是存放的数字是这个数字出现的次数&#xff0c;但是由…

Matlab论文插图绘制模板第137期—极坐标分组气泡图

在之前的文章中&#xff0c;分享了Matlab极坐标气泡图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一下极坐标分组气泡图。 先来看一下成品效果&#xff1a; ​ 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需要的朋…

解决SSH远程登录开饭板出现密码错误问题

输入“adduser Zhanggong回车”&#xff0c;使用adduser命令创建开发板用户名为Zhanggong 输入密码“123456” 输入密码“123456”

openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制

文章目录 openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制226.1 适用场景226.2 非适用场景 openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制 226.1 适用场景 支持LLVM的表达式 查询语句中存在以下的表达式支持…

网络安全-nc(Netcat)工具详解

经常在反弹shell的时候使用nc命令&#xff0c;但是从来没有了解过&#xff0c;今天翻书看到了&#xff0c;准备记录一下。 nc全称Netcat&#xff0c;是TCP/IP连接的瑞士军刀。哈哈我最喜欢瑞士军刀了。 有一个比较偏的知识点&#xff0c;nc还可以探测目标的端口是否开放&…

Modern C++ std::variant的5个特性+原理

1 前言 上一节《Modern C std::variant的实现原理》我们简单分析了std::variant的实现原理&#xff0c;其实要学好C编程&#xff0c;除了看优秀的代码包括标准库实现&#xff0c;读文档也是很便捷且必须的一种办法。 本节我将逐条解析文档中的五个特性&#xff0c;解析的办法有…

PYTHON-使用正则表达式进行模式匹配

目录 Python 正则表达式Finding Patterns of Text Without Regular ExpressionsFinding Patterns of Text with Regular ExpressionsCreating Regex ObjectsMatching Regex ObjectsReview of Regular Expression MatchingMore Pattern Matching with Regular ExpressionsGroupi…

阿里开源低代码引擎 - Low-Code Engine

阿里开源低代码引擎 - Low-Code Engine 本文主要介绍如何在Windows运行/开发阿里开源低代码引擎 - Low-Code Engine 详细文档参见【 阿里开源低代码引擎 - Low-Code Engine 官方文档】 目录 阿里开源低代码引擎 - Low-Code Engine一、环境准备1、使用 WSL 在 Windows 上安装 L…

Java学习笔记2024/2/22

面向对象进阶部分学习方法&#xff1a; 特点&#xff1a; 逻辑性没有那么强&#xff0c;但是概念会比较多。 记忆部分重要的概念&#xff0c;理解课堂上讲解的需要大家掌握的概念&#xff0c;多多练习代码。 今日内容 复习回顾 static关键字 继承 教学目标 能够掌握st…