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.pswp.cn/news/697497.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697497.shtml
英文地址,請注明出處:http://en.pswp.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;它允許我們在運行時將功能動態地添加到對象上&…