是什么
Spring Cloud Gateway匹配路由作为Spring WebFlux HandlerMapping
基础设施的一部分。 Spring Cloud Gateway包含许多内置的路由谓词工厂。 所有这些谓词都匹配HTTP请求的不同属性。 您可以使用逻辑 and
语句来联合收割机组合多个路由谓词工厂。
Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理。
分类
idea启动项目打印的日志:
常用的内置Route Predicate
id:我们自定义的路由 ID,保持唯一
uri:目标服务地址
predicates:路由条件,Predicate接受一个输入参数返回一个布尔值。
该属性包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)
配置语法总体概述
2种配置方式,二选一
短格式配置
完全展开配置
测试地址
http://localhost:9527/pay/gateway/get/1
After Route Predicate
After
路由谓词工厂接受一个datetime
参数(这是一个java ZonedDateTime
)。
在指定日期时间之后才可以请求该地址。
spring:cloud:gateway:routes:- id: after_routeuri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- After=2024-04-24T23:56:23.970133500+08:00[Asia/Shanghai]
如何获取ZonedDateTime
import java.time.ZonedDateTime;public class Testtt {public static void main(String[] args) {ZonedDateTime zonedDateTime = ZonedDateTime.now().plusMinutes(1); // 1分钟之后的时间System.out.println(zonedDateTime);}
}
Before Route Predicate
Before路由谓词工厂接受一个datetime参数(这是一个java ZonedDateTime)。
在指定日期时间之前才可以请求该地址。
spring:cloud:gateway:routes:- id: before_routeuri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Before=2024-04-25T00:02:10.783066100+08:00[Asia/Shanghai]
Between Route Predicate
Between路由谓词工厂接受两个参数,datetime1和datetime2(都是Java ZonedDateTime)。用英文逗号分隔。
在datetime1之后和datetime2之前可以请求该地址。
datetime2参数必须在datetime1之后。
spring:cloud:gateway:routes:- id: between_routeuri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Between=2024-04-24T23:56:23.970133500+08:00[Asia/Shanghai], 2024-04-25T00:02:10.783066100+08:00[Asia/Shanghai]
Cookie Route Predicate
Cookie Route Predicate需要两个参数,一个是 Cookie name ,一个是正则表达式。
路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。
spring:cloud:gateway:routes:- id: cookie_routeuri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Cookie=chocolate, ch.p
Header Route Predicate
Header路由谓词工厂接受两个参数,header和regexp(这是一个Java正则表达式)。
此谓词与具有给定名称且其值与正则表达式匹配的标头匹配。
spring:cloud:service-name: ${spring.application.name}gateway:routes:- id: header_routeuri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Header=X-Request-Id, [0-9]+
Host Route Predicate
Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。
它通过参数中的主机地址作为匹配规则。
spring:cloud:gateway:routes:- id: pay_routh1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Host=**.somehost.org,**.anotherhost.org
Path Route Predicate
路径相匹配的进行路由
spring:cloud:gateway:routes:- id: pay_routh1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**
Query Route Predica
Query路由谓词工厂有两个参数:一个必需的param和一个可选的regexp(这是一个Java正则表达式)。
请求包含param查询参数。
spring:cloud:gateway:routes:- id: pay_routh1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Query=green
RemoteAddr route predicate
RemoteAddr路由断言工厂采用sources的列表(最小大小为1),这些列表是CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。
什么是计算机网络中的 CIDR
spring:cloud:gateway:routes:- id: pay_routh1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- RemoteAddr=192.168.31.171/24
Method Route Predicat
Method路由谓词工厂接受一个methods参数,它是一个或多个参数:要匹配的HTTP方法。
配置某个请求地址,只能用Get/Post方法访问,方法限制。
spring:cloud:gateway:routes:- id: pay_routh1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- Method=GET,POST
Weight Route Predicat
Weight路由谓词工厂有两个参数:group和weight(一个int)。计算每组的权重。
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2
该路由将把80%的流量转发到weightthigh.org,20%的流量转发到weightlow.org。
自定义断言
规则:
要么继承AbstractRoutePredicateFactory抽象类
要么实现RoutePredicateFactory接口
开头任意取名,但是必须以RoutePredicateFactory后缀结尾
仿照:AfterRoutePredicateFactory
自定义XXXRoutePredicateFactory
1. 新建类名XXX需要以RoutePredicateFactory结尾,并继承AbstractRoutePredicateFactory类。
2. 重写apply方法
3. 新建apply方法所需要的静态内部类MyRoutePredicateFactory.Config,这个Config类就是我们的路由断言规则,重要
4. 空参构造方法,内部调用super
5. 重载 shortcutFieldOrder 方法
不重载,配置的时候只能完全展开配置,不能短格式配置。
package com.yq.springcloud.predicate;import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
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;public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {public static final String PARAM_USERTYPE = "userType";public MyRoutePredicateFactory() {super(Config.class);}/*** 返回有关参数数和快捷方式分析顺序的提示* @return*/@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList(PARAM_USERTYPE);}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return serverWebExchange -> {//检查request的参数里面,userType是否为指定的值,符合配置就通过String userType = serverWebExchange.getRequest().getQueryParams().getFirst(PARAM_USERTYPE);if (userType == null) return false;//如果说参数存在,就和config的数据进行比较if (userType.equals(config.getUserType())) {return true;}return false;};}@Validated@Datapublic static class Config {@NotBlankprivate String userType; //钻、金、银等用户等级}
}
自定义GatewayAutoConfiguration
仿照:org.springframework.cloud.gateway.config.GatewayAutoConfiguration
将自己自定义的断言加入IOC
package com.yq.springcloud.config;import com.yq.springcloud.predicate.MyRoutePredicateFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration;
import org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration;
import org.springframework.cloud.gateway.config.conditional.ConditionalOnEnabledPredicate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class,GatewayClassPathWarningAutoConfiguration.class })
public class MyGatewayAutoConfiguration {@Bean@ConditionalOnEnabledPredicatepublic MyRoutePredicateFactory myRoutePredicateFactory() {return new MyRoutePredicateFactory();}
}
配置文件中添加配置断言
spring:cloud:gateway:routes:- id: pay_routh1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**- My=diamond
测试
1, 启动的时候,已加载到断言中
2. 只有userType=diamond才可以正常访问。