Predicate
Predicate 是 Java8 提供的函数时编程接口 , 接收参数并返回一个 boolean 值 , 用于条件过过滤 , 请求参数的校验
定义一个Predicate
java
/**
* 判断字符串是否为空
* 空 -true
* 非空 -false
*/
public class StringPredicate implements Predicate<String> {
@Override
public boolean test(String s) {
return s == null || s.isEmpty();
}
}
在测试类中调用这个方法
① 常规用法
java
@Test
public void test(){
Predicate<String> predicate = new StringPredicate();
System.out.println(predicate.test(""));
System.out.println(predicate.test("aa"));
}

② 匿名内部类
java
@Test
public void test2(){
Predicate<String> predicate = new StringPredicate(){
public boolean test(String s){
return s.isEmpty();
}
};
System.out.println(predicate.test(""));
System.out.println(predicate.test("aa"));
}
③lambda 写法
java
@Test
public void test3(){
Predicate<String> predicate = s->s == null||s.isEmpty();
System.out.println(predicate.test(""));
System.out.println(predicate.test("aa"));
}


Route Predicate Factories(路由断言工厂)
在 Spring Cloud Gateway 中 , Predicate 提供了路由规则的匹配机制
在配置文件中 写的断言规则只是字符串 , 这些字符串会被 Route Predicate Factories 读取并处理 , 转变为路由判断的条件

官网 : Route Predicate Factories :: Spring Cloud Gateway
结合官网提供以下示例 :
|------------|-----------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| After | 匹配指定日期时间之后的请求。需要一个 Java ZonedDateTime 对象作为参数。 | predicates: - After=2017-01-20T17:42:47.789-07:00America/Denver |
| Before | 匹配指定日期时间之前的请求。需要一个 Java ZonedDateTime 对象作为参数。 | predicates: - Before=2017-01-20T17:42:47.789-07:00America/Denver |
| Between | 匹配两个指定日期时间之间的请求。需要两个 Java ZonedDateTime 对象作为参数,第二个参数必须在第一个参数之后。 | predicates: - Between=2017-01-20T17:42:47.789-07:00America/Denver, 2017-01-21T17:42:47.789-07:00America/Denver |
| Cookie | 匹配请求中包含指定 Cookie 名称,且其值符合指定正则表达式的请求。参数格式为:name, regexp。 | predicates: - Cookie=chocolate, ch.p |
| Header | 匹配请求中包含指定 Header 名称,且其值符合指定正则表达式的请求。参数格式为:name, regexp。 | predicates: - Header=X-Request-Id, \d+ |
| Host | 匹配请求的 Host 头字段符合指定模式。支持 Ant 风格的路径匹配(如 **)。多个模式用逗号分隔。 | predicates: - Host=**.somehost.org, **.anotherhost.org |
| Method | 匹配指定的 HTTP 请求方法(如 GET, POST, PUT 等)。多个方法用逗号分隔。 | predicates: - Method=GET, POST |
| Path | 匹配请求的 URL 路径符合指定模式。支持 Ant 风格的路径匹配和路径变量(如 {segment})。 | predicates: - Path=/red/{segment}/blue/{segment} |
| RemoteAddr | 匹配请求的远程 IP 地址在指定范围内。支持 CIDR 表示法(如 /24)。多个地址用逗号分隔。 | predicates: - RemoteAddr=192.168.1.1/24 |
Gateway Filter factories (网关过滤工厂)
Predicate 决定了请求由哪一个路由处理 , 如果在请求处理前后需要加一些逻辑 , 这需要 Filter (过滤器)
按执行时机分为两种类型 : Pre 和 Post 类型
- Pre 类型过滤器 : 路由处理之前执行 (请求转发到后端服务之前执行) , Pre 类型过滤器中可以做鉴权 , 限流等
- Post 类型过滤器 : 请求执行完成后执行 (将结果返回给客户端之前执行)
按作用范围分为 : GatewayFilter 和 GlobalFilter
- GatewayFilter : 应用到单个路由或者一个分组的路由上
- GlobalFilter : 应用到所有到的路由上
GatewayFilter :
添加 gateway 的配置文件中添加 filter


此 filter 只在 order-service 下生效 , 效果是在所有的请求中加上参数 userName : bite
此处不做示范 , 需要修改大量代码
继续阅读官网 : AddRequestHeader GatewayFilter Factory :: Spring Cloud Gateway

此目录下包含大量 filter


GlobalFilter
GlobalFilter 是 Spring Cloud Gateway 中的全局过滤器 , 和 GatewayFilter 的作用几乎相同
参考官网 : Global Filters :: Spring Cloud Gateway

①gateway 的 pom 添加依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
</dependency>
② gateway 的配置文件中添加配置
spring:
cloud:
gateway:
metrics:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
shutdown:
enabled: true
- Spring Cloud Gateway 指标配置

- 作用:开启 Spring Cloud Gateway 的网关指标收集功能
- 详细说明 :当设置为
true时,网关会收集一系列与运行相关的指标数据(如路由ID、转发URI、HTTP状态码、请求耗时等)。这些数据能够帮助开发者和运维人员更好地了解网关的运行状态、性能表现以及流量情况,且通常可方便地与 Prometheus 等工具集成以创建监控面板
- Actuator 端点暴露配置

- 作用:控制哪些 Actuator 端点可以通过 HTTP 对外暴露访问
- 详细说明 :
include: "*"表示暴露所有的 Actuator 监控端点(如/health、/info、/metrics、/env、/beans等)。默认情况下,出于安全考虑,Spring Boot 仅暴露/health和/info
- 健康检查详情配置

- 作用 :控制访问
/actuator/health端点时,是否展示各个组件的详细健康信息 - 详细说明 :设置为
always表示对所有访问者始终展示详细的健康报告(如数据库连接状态、Redis状态、磁盘空间使用率等)。该属性还支持never(默认,仅显示 UP/DOWN 状态)和when-authorized(仅向通过认证的用户展示详情)
- 远程关闭服务配置

- 作用:开启 Actuator 的远程优雅关闭应用功能
- 详细说明 :默认情况下该功能是禁用的(
false)。当设置为true时,允许通过向/actuator/shutdown端点发送POST请求来远程关闭应用程序
测试http://127.0.0.1:10030/actuator 查看本地运行的 Spring Boot 应用程序的"健康状况总览面板"

过滤器执行的先后顺序
- spring 提供的 filter 都有默认的 order 值 , order 值越小 , 越优先执行 ; 当 order 值相同时按defaultFilter > GatewayFilter > GlobalFilter执行
- 可以通过自定义 filter 来指定 order ; Filter 通过实现 Order()接口或者添加@Order 注解来指定 order 值
自定义 filter
①GatewayFilter
CustomGatewayFilterFactory (必须以****GatewayFilterFactory 命名)
java
package com.boop.gateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class CustomGatewayFilterFactory
extends AbstractGatewayFilterFactory<CustomConfig>
implements Ordered {
public CustomGatewayFilterFactory(){
super(CustomConfig.class);
}
@Override
public GatewayFilter apply(CustomConfig config) {
/**
* Mono<void> filter (ServerWebExchange exchange,GatewayFilterChain chain)
* ServerWebExchange: http请求-响应交互的契约, 提供对http请求和响应的访问, 服务器端请求属性, 请求示例,响应示例等, 类似Context角色
* GatewayFilterChain: 过滤器连
* Mono: Reactor核心类, 数据流发布者, Mono最多只触发一个事件, 所以可以把Mono用于一步任务完成时发出的通知
* Mono.fromRunnable: 创建一个包含Runnable元素的数据流
*/
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// [Pre] 前置处理逻辑
log.info("[Pre] Filter Request, name:" + config.getName());
// 继续执行过滤器链,并在链执行完毕后执行后置逻辑
return chain.filter(exchange).then(Mono.fromRunnable(new Runnable() {
@Override
public void run() {
// [Post] 后置处理逻辑
log.info("[Post] Response Filter");
}
}));
}
};
}
// public GatewayFilter apply(CustomConfig config) {
/**
* Mono<void> filter (ServerWebExchange exchange,GatewayFilterChain chain)
* ServerWebExchange: http请求-响应交互的契约, 提供对http请求和响应的访问, 服务器端请求属性, 请求示例,响应示例等, 类似Context角色
* GatewayFilterChain: 过滤器连
* Mono: Reactor核心类, 数据流发布者, Mono最多只触发一个事件, 所以可以把Mono用于一步任务完成时发出的通知
* Mono.fromRunnable: 创建一个包含Runnable元素的数据流
*/
// return (((exchange, chain) -> {
// log.info("[Pre] Filter Request, name:"+config.getName());
// return chain.filter(exchange).then(Mono.fromRunnable(()->{
// log.info("[Post] Response Filter");
// }));
// }));
// }
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;//配置优先级,order越大,优先级越低
}
}
注意 :
- 类名统一以 ****GatewayFilterFactory 命名 , 默认情况下 , 过滤器的 name 会采用该定义类的前缀 此处的 name = Custom
- apply 中 , 包含 Pre 和 Post 过滤 , then 方法中是请求执行结束之后处理的
- CustomConfig 是一个配置类 , 该类只有一个属性 name , 和 yml 的配置对应
- 需要 @Component 注解 , 交给 Spring 统一管理
- getOrger 表示该过滤器的优先级 , 值越大 , 优先级越高
CustomConfig
java
@Data
public class CustomConfig {
private String name;
}
gateway 的配置文件
html
spring:
cloud:
gateway:
routes: # 网关路由配置
- id: product-service # 路由ID,自定义,唯一即可
uri: lb://product-service # 目标服务地址
predicates: # 路由条件
- Path=/product/**
filters:
- name: Custom
args:
name: custom filter

测试 : http://127.0.0.1:10030/order/1
测试时最好测试多次请求 , 第一次启动服务会有初始化信息的日志

②GlobalFilter
实现方式比较简单 只需要实现GlobalFilter,Ordered 两个接口 , 就自动会过滤所有的 Filter
CustomGlobalFilter
java
@Component
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Pre Global Filter");
return chain.filter(exchange).then(Mono.fromRunnable(()->{
log.info("Post Global Filter...");
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
注意 : GlobalFilter 与 GatewayFilter 运行方式不同 , GlobalFilter 不需要遵守类名后缀的规则 , 只需要继承GlobalFilter, Ordered 并加上@Component 注解 就会被自动识别
测试 : http://127.0.0.1:10030/order/1
同上 : 测试时最好测试多次请求 , 第一次启动服务会有初始化信息的日志
