SpringCloud 2023 Gateway的Predicate配置详解、自定义Route Predicate Factory

news/2024/9/28 12:10:27/

目录

  • 1. Predicate Factories介绍
  • 2. 常用的内置Route Predicate使用
    • 2.1 配置语法说明
    • 2.2 配置使用
  • 3. 自定义Route Predicate Factory
    • 3.1 实现步骤:
    • 3.2 实现代码如下:
    • 3.3 application.yml配置
    • 3.4 测试

1. Predicate Factories介绍

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。包含共12种内置的Route Predicate Factory,可以配置多个Route Predicate Factory,用逻辑and进行组合,如果HTTP请求的不同属性满足条件,则跳转到指定的route路由
Predicate Factories介绍

启动Spring Cloud Gateway服务时,日志会打印加载的Route Predicate Factory,如下所示。所有Route Predicate Factory的父类都是RoutePredicateFactory

2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [After]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Before]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Between]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Cookie]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Header]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Host]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Method]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Path]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Query]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [ReadBody]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [RemoteAddr]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [XForwardedRemoteAddr]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Weight]
2024-08-09T11:13:00.258+08:00  INFO 17080 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [CloudFoundryRouteService]

2. 常用的内置Route Predicate使用

2.1 配置语法说明

提供了两种配置语法:

  • 快捷语法(常用):filter名称=filter值,filter值用逗号分隔
spring:cloud:gateway:routes:- id: payRoute                  uri: lb://payment              predicates:- Path=/pay/**              - Cookie=cookieKey,cookieValue  # 需同时匹配Path和Cookie,HTTP请求的Cookie的key需要为cookieKey,value需要为cookieValue
  • 全部展开语法
spring:cloud:gateway:routes:- id: payRoute                  uri: lb://payment              predicates:- Path=/pay/**              - name: Cookie  # 需同时匹配Path和Cookie,HTTP请求的Cookie的key需要为cookieKey,value需要为cookieValueargs:name: cookieKeyregexp: cookieValue

2.2 配置使用

  • After Route Predicate: 在指定时间之后发送的HTTP请求才符合要求。常用于秒杀、抢购。时间参数值可以通过System.out.println(ZonedDateTime.now())
    • 配置: - After=2024-08-09T13:28:40.332233100+08:00[Asia/Shanghai]
    • 效果: 在13:27分的时候向网关http://localhost:8088/pay/get/1发送请求报404,在13:29分的时候向网关发送请求成功
  • Before Route Predicate: 在指定时间之前发送的HTTP请求才符合要求。时间参数值可以通过System.out.println(ZonedDateTime.now())
    • 配置: - Before=2024-08-09T13:32:40.332233100+08:00[Asia/Shanghai]
    • 效果: 在13:31分的时候向网关发送请求成功,在13:33分的时候向网关http://localhost:8088/pay/get/1发送请求报404
  • Between Route Predicate: 在指定时间之间发送的HTTP请求才符合要求。时间参数值可以通过System.out.println(ZonedDateTime.now())
    • 配置: - Between=2024-08-09T13:33:40.332233100+08:00[Asia/Shanghai],2024-08-09T13:36:40.332233100+08:00[Asia/Shanghai]
    • 效果: 在13:32分的时候向网关http://localhost:8088/pay/get/1发送请求报404,在13:35分的时候向网关发送请求成功,在13:37分的时候向网关http://localhost:8088/pay/get/1发送请求报404
  • Cookie Route Predicate: 需要两个参数,一个是Cookie name ,一个是正则表达式。路由规则会通过获取对应的Cookie name值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
    • 配置: - Cookie=username,lily
    • 效果:执行curl http://localhost:8088/pay/get/1向网关发送请求报404,执行curl http://localhost:8088/pay/get/1 --cookie "username=lily"向网关发送请求成功
  • Header Route Predicate: 需要两个参数,一个是属性名称 ,一个是正则表达式。路由规则会通过获取对应的Header的属性名称和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
    • 配置: - Header=requestId, \d+。说明:请求头要有requestId属性, 并且值为整数的正则表达式
    • 效果:执行curl http://localhost:8088/pay/get/1向网关发送请求报404,执行curl http://localhost:8088/pay/get/1 -H "requestId:123456"向网关发送请求成功
  • Host Route Predicate: 接收一组参数,即一组匹配的域名列表,域名是Ant风格模式的,用逗号分隔。路由规则会通过获取对应的Header的Host的值去匹配,如果匹配上任意一个域名就会执行路由,如果没有匹配上则不执行
    • 配置: - Host=**.h1.com,**.h2.com。说明:请求头的Host匹配任意域名都可以
    • 效果:执行curl http://localhost:8088/pay/get/1 -H "Host:nb.h0.com"向网关发送请求报404,执行curl http://localhost:8088/pay/get/1 -H "Host:nb.h1.com"向网关发送请求成功,执行curl http://localhost:8088/pay/get/1 -H "Host:nb.h2.com"向网关发送请求成功
  • Path Route Predicate: 接收一组参数,即一组匹配的路径列表,路径是Ant风格模式的,用逗号分隔。路由规则会通过获取对应的path路径的值去匹配,如果匹配上任意一个路径就会执行路由,如果没有匹配上则不执行
    • 配置: - Path=/pay/get/{segment},/pay/list/**
    • 效果:向网关发送http://localhost:8088/pay/get2/1请求报404,向网关发送http://localhost:8088/pay/get/1请求成功,向网关发送http://localhost:8088/pay/list/detail/1请求成功
  • Query Route Predicate: 需要两个参数,一个是请求参数名称 ,一个是正则表达式。路由规则会通过获取对应的请求参数的名称和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
    • 配置: - Query=username, \d+。说明:请求参数要有username名称, 并且其值为整数的正则表达式
    • 效果:执行curl http://localhost:8088/pay/get/1向网关发送请求报404,执行curl http://localhost:8088/pay/get/1?username=123456"向网关发送请求成功
  • RemoteAddr Route Predicate: 接收一组参数,即一组匹配的远程地址列表,远程地址是CIDR(无类域间路由),用逗号分隔。路由规则会通过获取对应的远程地址的值去匹配,如果匹配上任意一个远程地址就会执行路由,如果没有匹配上则不执行
    • CIDR(无类域间路由):支持IPV4和IPV6, 一个形如255.255.255.255的ip地址共32位。72.108.25.1/24无类域间路由表示前24位是网络地址,则只有8位是主机地址,所以主机范围为72.108.25.072.108.25.25572.109.25.2/30无类域间路由表示前30位是网络地址,则只有2位是主机地址,所以主机范围为72.109.25.072.109.25.3
    • 配置: - RemoteAddr=72.108.25.1/24,72.109.25.2/30
    • 效果:从ip为72.107.25.8的服务器向网关发送http://10.8.12.67:8088/pay/get/1请求报404,从ip为72.108.25.18的服务器向网关发送http://10.8.12.67:8088/pay/get/1请求成功,从ip为72.109.25.3的服务器向网关发送http://10.8.12.67:8088/pay/get/1请求成功
  • Method Route Predicate: 接收一组参数,即一组匹配的请求方式列表,用逗号分隔。路由规则会通过获取对应的请求方式的值去匹配,如果匹配上任意一个请求方式就会执行路由,如果没有匹配上则不执行
    • 配置: - Method=GET,POST
    • 效果:以PUT方式向网关发送http://10.8.12.67:8088/pay/get/1请求报404,以GET方式向网关发送http://10.8.12.67:8088/pay/get/1请求成功,以POST方式向网关发送http://10.8.12.67:8088/pay/get/1请求成功

3. 自定义Route Predicate Factory

3.1 实现步骤:

  1. gatewayServer项目中新建自定义Predicate Factory类MyRoutePredicateFactory。类名的后缀必须是RoutePredicateFactory。所以这里创建的是一个My Route Predicate
  2. 类继承AbstractRoutePredicateFactory。也可以继承RoutePredicateFactory接口
  3. 实现无参构造器,调用父类的构造器
  4. 实现一个配置类MyRoutePredicateFactory.Config,定义需要验证的值userType
  5. 重写父类的apply方法,实现匹配userType成功和失败的逻辑
  6. 重写父类的shortcutFieldOrder方法,让其支持shortcut语法

3.2 实现代码如下:

import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config>
{public MyRoutePredicateFactory(){super(MyRoutePredicateFactory.Config.class);}@Validated  // 用@validated来校验数据,如果数据异常会统一抛出异常public static class Config {   @Setter@Getter@NotEmptyprivate String userType;     // 验证用户类型}@Overridepublic Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config){return new Predicate<ServerWebExchange>(){@Overridepublic boolean test(ServerWebExchange serverWebExchange){// 获取request参数中的userTypeString userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");if (userType == null) return false;// 如果request参数中的userType的值,和gatewayServer配置文件中配置的值相等,则符合条件if(userType.equals(config.getUserType())) return true;return false;}};}@Overridepublic List<String> shortcutFieldOrder() {// 列表: [userType]return Collections.singletonList("userType");}}

3.3 application.yml配置

全部展开语法配置如下:

            - name: Myargs:userType: gold

快捷语法配置: - My=gold

3.4 测试

启动gatewayServer项目,会打印如下日志,表示加载My Route Predicate成功

2024-08-09T17:58:37.861+08:00  INFO 5220 --- [gatewayServer] [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [My]

向网关发送http://localhost:8088/pay/get/1请求报404,向网关发送http://localhost:8088/pay/get/1?userType=gold请求成功


http://www.ppmy.cn/news/1531157.html

相关文章

智能PPT行业赋能用户画像

智能PPT市场在巨大的需求前景下&#xff0c;已吸引一批不同类型的玩家投入参与竞争。从参与玩家类型来看&#xff0c;不乏各类与PPT创作有关的上下游企业逐步向智能PPT赛道转型进入&#xff0c;也包括顺应生成式AI技术热潮所推出的创业企业玩家。当前&#xff0c;智能PPT赛道发…

打造同城O2O平台:外卖跑腿APP的架构与功能设计详解

今天&#xff0c;小编将于大家共同讨论外卖跑腿APP的架构设计及其核心功能&#xff0c;旨在为开发者提供一份详尽的参考。 一、外卖跑腿APP的架构设计 1.整体架构概述 通常包括前端、后端和数据库。 2.前端设计 用户端提供直观的界面&#xff0c;方便用户下单、查询订单状态…

error -- unsupported GNU version gcc later than 10 are not supported;(gcc、g++)

服务器跑dit时编译flash-atten以及pytorch的cuda版本检查出错&#xff0c;分别报错题目以及如下&#xff1a; 想了下是系统找不到编译器 subprocess.CalledProcessError: Command [which, c] returned non-zero exit status 1. 备案&#xff0c;以后有人要用12我还得换回来 …

Lab1 Xv6 and Unix utilities

Lab1 Xv6 and Unix utilities 目的是为了熟悉xv6和一些它的系统调用函数 Boot xv6(easy) 1.环境 环境我是用的vscode配置的wsl&#xff0c;系统是ubuntu 20.04。用虚拟机、云服务器都感觉差不多。 网上看到Ubuntu 22.04 版本不适用于20年的课程&#xff0c;在根据20年课程…

vscode【实用插件】Project Manager 项目管理

安装 在 vscode 插件市场的搜索 Project Manager点 安装 安装成功后&#xff0c;vscode 左侧栏会出现 使用 将项目添加到项目列表中 用 vscode 打开项目&#xff0c;点保存即可 将项目移出项目列表 切换项目 单击项目列表中的项目&#xff0c;即可切换到目标项目 新窗口打开…

MySQL数据库进阶知识(五)《锁》

学习目标&#xff1a; 一周掌握数据库锁相关知识 学习内容&#xff1a; 一. 概述 介绍 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共…

数学建模运筹优化——规划问题Python版(线性、非线性、整数、0/1)

数学建模运筹优化——规划问题Python版&#xff08;线性、非线性、整数、0/1&#xff09;_python 运筹优化‘-CSDN博客

selenium模块入门

一、selenium selenium是一个用于web应用程序自动化测试工具&#xff0c;selenium测试直接运行在浏览器。 二、selenium的运用场景以及安装 selenium支持主流浏览器 selenium支持Java、python、ruby、c#&#xff0c;JavaScript、c等多种语言 selenium支持Linux、Windows、m…