需求:对于本次请求的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 #以微服务注册进consulcloud: consul: #配置consul地址host: localhostport: 8500 discovery: prefer- ip- address: true service- name: ${ spring. application. name} gateway: routes: - id: pay_routh1uri: lb: / / cloud- payment- servicepredicates: - My = userType, VIP
效果:
· cookie中userType不是VIP时,请求不受理:
· cookie中userType是VIP时,正常查询: