自定义断言
- 新增一个Bean 标记为@Component、
- 继承
AbstractRoutePredicateFactory
类命名需要以RoutePredicateFactory
结尾 - 声明一个静态内部类 来接受配置文件中的信息
- 重写 shortcutFieldOrder 来映射 配置文件中的参数
- 重写apply方法
- 继承
下面是一个根据 请求头和时间 来决定是否放心请求的例子
yaml配置
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: user_router
uri: lb://user-service
predicates:
- Path=/user-serv/**
#当请求的为FirstHeader 值为 FirstValue 时间在2024-01-19 之前的请求放行到user-service服务
- Custom=test, testValue,2024-01-19
filters:
- StripPrefix=1
实现类
package com.cckeep.gateway.predicates;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.function.Predicate;
@Component
@Slf4j
public class CustomRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomRoutePredicateFactory.Config> {
//需要与前面配置文文件中第一个值名称一致 因为前面我业务上把第一个当做请求头head
private static final String HEAD_KEY = "test";
public CustomRoutePredicateFactory() {
super(Config.class);
}
//把前面配置文件的值通过set方法按顺序 映射到 Config
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("head", "value", "limitTime");
}
@Validated
public static class Config {
@Setter
@Getter
private String head;
@Setter
@Getter
private String value;
@Getter
private Date limitTime;
public Config() {
}
// 读取配置文件出来的是String 所以这里重写set方法
public void setLimitTime(String limitTime) {
try {
this.limitTime = new SimpleDateFormat("yyyy-MM-dd").parse(limitTime);
} catch (ParseException e) {
log.error("格式化时间错误");
throw new RuntimeException(e);
}
}
}
@Override
//真正处理逻辑的地方
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
List<String> heads = serverWebExchange.getRequest().getHeaders().getOrDefault(HEAD_KEY, Collections.emptyList());
if (heads.isEmpty()) {
return false;
}
for (int i = 0; i < heads.size(); i++) {
if (config.getValue().equals(heads.get(i)) && new Date().before(config.getLimitTime())) {
return true;
}
}
return false;
}
};
}
}
测试
这是我的controller
通过apiPost发请求测试
当请求头 和值 与配置一致时候请求成功