是什么
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_route
uri: lb://cloud-payment-service
predicates:
- 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_route
uri: lb://cloud-payment-service
predicates:
- 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_route
uri: lb://cloud-payment-service
predicates:
- 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_route
uri: lb://cloud-payment-service
predicates:
- 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_route
uri: lb://cloud-payment-service
predicates:
- Path=/pay/gateway/get/**
- Header=X-Request-Id, [0-9]+
Host Route Predicate
Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。
它通过参数中的主机地址作为匹配规则。
spring:
cloud:
gateway:
routes:
- id: pay_routh1
uri: lb://cloud-payment-service
predicates:
- Path=/pay/gateway/get/**
- Host=**.somehost.org,**.anotherhost.org
Path Route Predicate
路径相匹配的进行路由
spring:
cloud:
gateway:
routes:
- id: pay_routh1
uri: lb://cloud-payment-service
predicates:
- Path=/pay/gateway/get/**
Query Route Predica
Query路由谓词工厂有两个参数:一个必需的param和一个可选的regexp(这是一个Java正则表达式)。
请求包含param查询参数。
spring:
cloud:
gateway:
routes:
- id: pay_routh1
uri: lb://cloud-payment-service
predicates:
- 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_routh1
uri: lb://cloud-payment-service
predicates:
- Path=/pay/gateway/get/**
- RemoteAddr=192.168.31.171/24
Method Route Predicat
Method路由谓词工厂接受一个methods参数,它是一个或多个参数:要匹配的HTTP方法。
配置某个请求地址,只能用Get/Post方法访问,方法限制。
spring:
cloud:
gateway:
routes:
- id: pay_routh1
uri: lb://cloud-payment-service
predicates:
- Path=/pay/gateway/get/**
- Method=GET,POST
Weight Route Predicat
Weight路由谓词工厂有两个参数:group和weight(一个int)。计算每组的权重。
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- 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
*/
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList(PARAM_USERTYPE);
}
@Override
public 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
@Data
public static class Config {
@NotBlank
private 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
@ConditionalOnEnabledPredicate
public MyRoutePredicateFactory myRoutePredicateFactory() {
return new MyRoutePredicateFactory();
}
}
配置文件中添加配置断言
spring:
cloud:
gateway:
routes:
- id: pay_routh1
uri: lb://cloud-payment-service
predicates:
- Path=/pay/gateway/get/**
- My=diamond
测试
1, 启动的时候,已加载到断言中
2. 只有userType=diamond才可以正常访问。