需求:对于本次请求的cookie中,如果userType不是vip的身份,不予访问
思路:因为要按照cookie参数进行判断,所以根据官方自带的CookieRoutePredicateFactory进行改造
- 创建自己的断言类,命名必须符合
xxxRoutePredicateFactory
的规范,其中xxx就是配置文件中 predicates
中的key,我的类名是MyRoutePredicateFactory
,所以配置文件中配置的就是 My
,下面图中会标示 - 继承统一的抽象类
AbstractRoutePredicateFactory
- 完善断言类型(我使用的是官方也使用的短配置
shortcutFieldOrder
)、构造方法以及断言逻辑方法 apply
- 定义自己的内部配置类
Config
,其中的 name
和 regexp
就是断言的属性和值(或者正则,本次只判断值是否相等),需注意这里就不敢直接自动生成set和get方法了,因为官方要求的是Config中的属性所使用的set方法必须返回本Config对象,如图:
代码如下:
import jakarta.validation.constraints.NotEmpty;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.HttpCookie;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
public List<String> shortcutFieldOrder() {
return Arrays.asList("name", "regexp");
}
public MyRoutePredicateFactory(){
super(MyRoutePredicateFactory.Config.class);
}
public Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {
return new GatewayPredicate() {
public boolean test(ServerWebExchange exchange) {
List<HttpCookie> cookies = (List)exchange.getRequest().getCookies().get(config.name);
if (cookies == null) {
return false;
} else {
Iterator cookieIterator = cookies.iterator();
HttpCookie cookie;
do {
if (!cookieIterator.hasNext()) {
return false;
}
cookie = (HttpCookie)cookieIterator.next();
} while(!config.regexp.equals(cookie.getValue()));
return true;
}
}
public Object getConfig() {
return config;
}
public String toString() {
return String.format("Cookie: name=%s regexp=%s", config.name, config.regexp);
}
};
}
@Validated
public static class Config {
@NotEmpty
private String name;
@NotEmpty
private String regexp;
public Config() {
}
public String getName() {
return this.name;
}
public MyRoutePredicateFactory.Config setName(String name) {
this.name = name;
return this;
}
public String getRegexp() {
return regexp;
}
public MyRoutePredicateFactory.Config setRegexp(String regexp) {
this.regexp = regexp;
return this;
}
}
}
配置文件如图:
配置代码:
spring:
application:
name: cloud-gateway #以微服务注册进consul
cloud:
consul: #配置consul地址
host: localhost
port: 8500
discovery:
prefer-ip-address: true
service-name: ${spring.application.name}
gateway:
routes:
- id: pay_routh1
uri: lb://cloud-payment-service
predicates:
- My=userType,VIP
效果:
· cookie中userType不是VIP时,请求不受理:
· cookie中userType是VIP时,正常查询: