【GateWay】自定义RoutePredicateFactory

需求:对于本次请求的cookie中,如果userType不是vip的身份,不予访问

思路:因为要按照cookie参数进行判断,所以根据官方自带的CookieRoutePredicateFactory进行改造

  1. 创建自己的断言类,命名必须符合 xxxRoutePredicateFactory 的规范,其中xxx就是配置文件中 predicates 中的key,我的类名是MyRoutePredicateFactory ,所以配置文件中配置的就是 My ,下面图中会标示
  2. 继承统一的抽象类 AbstractRoutePredicateFactory
  3. 完善断言类型(我使用的是官方也使用的短配置 shortcutFieldOrder )、构造方法以及断言逻辑方法 apply
  4. 定义自己的内部配置类 Config ,其中的 nameregexp 就是断言的属性和值(或者正则,本次只判断值是否相等),需注意这里就不敢直接自动生成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;

/**
 * 对于请求的cookie中,如果userType不是vip,不予访问
 */
@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时,正常查询:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值