SpringCloud Gateway自定义断言工厂

当官方提供的所有断言工厂无法满足业务需求时,还可以自定义断言工厂。

添加自定义断言工厂类

自定断言工厂主要注意一下几点:

  • 需要声明是Springboot的Bean,添加注解@Component,名称必须以RoutePredicateFactory结尾,这个是命名约束。
  • 如果不按照命名约束来命名,那么就会找不到该断言工厂。前缀就是配置中配置的断言。
  • 可以直接复制Gateway中已经实现的断言工厂,修改对应的内容,避免踩坑。
  • 继承父类AbstractRoutePredicateFactory,并重写方法。
  • 需要定义一个Config静态内部类,来接收断言配置的数据。
  • 在重写的shortcutFieldOrder方法中,绑定Config中的属性。传入数组的内容需要与Config中的属性一致。
  • 在重写的apply方法中,实现具体验证逻辑。
import com.alibaba.cloud.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * @ClassName CustomVerifyRoutePredicateFactory
 * @Description 
 * @Author tigerkin
 * @Date 2022/3/14 15:15
 */
@Component
public class CustomVerifyRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomVerifyRoutePredicateFactory.Config> {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 验证内容 key.
     */
    public static final String VERIFY_CONTENT_KEY = "verifyContentKey";

    /**
     * 验证内容 val.
     */
    public static final String VERIFY_CONTENT_VAL = "verifyContentVal";

    public CustomVerifyRoutePredicateFactory() {
        super(CustomVerifyRoutePredicateFactory.Config.class);
    }

    /**
     * 将签名 key 与 静态类Config中的属性进行绑定
     * 数组里面下标对应配置文件中配置
     *
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(VERIFY_CONTENT_KEY, VERIFY_CONTENT_VAL);
    }

    @Override
    public Predicate<ServerWebExchange> apply(CustomVerifyRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {

            /**
             * 断言验证逻辑,返回true,则验证成功,否则失败
             *
             * @param serverWebExchange
             * @return
             */
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                HttpHeaders headers = serverWebExchange.getRequest().getHeaders();
                String headerVal = headers.getFirst(config.getVerifyContentKey());
                boolean result = StringUtils.equals(headerVal, config.getVerifyContentVal());

                log.info("========> 自定义断言配置 key:{} val:{}", config.getVerifyContentKey(), config.getVerifyContentVal());
                log.info("========> 自定义断言验证 status:{} val:{}", result, headerVal);
                return result;
            }

            @Override
            public Object getConfig() {
                return config;
            }

            @Override
            public String toString() {
                return String.format("key: %s, val: %s", config.getVerifyContentKey(), config.getVerifyContentVal());
            }
        };
    }

    /**
     * 定义静态类,接收自定义断言的配置信息
     */
    public static class Config {

        @NotNull
        private String verifyContentKey;

        @NotNull
        private String verifyContentVal;

        public String getVerifyContentKey() {
            return verifyContentKey;
        }

        public void setVerifyContentKey(String verifyContentKey) {
            this.verifyContentKey = verifyContentKey;
        }

        public String getVerifyContentVal() {
            return verifyContentVal;
        }

        public void setVerifyContentVal(String verifyContentVal) {
            this.verifyContentVal = verifyContentVal;
        }
    }
}

配置自定义的断言工厂

spring:
  cloud:
    gateway:
      routes:
        - id: user-route # 路由ID,唯一标识,自定义命名
          uri: lb://gateway-user
          predicates:
            - Path=/user-server/**
            # 自定义的断言工厂,多个参数按逗号(,)隔开,参数对应断言工厂中shortcutFieldOrder方法定义的数组,一一对应。
            - CustomVerify=verify, success 

到这里自定义断言工厂就完成了!!!

猜你喜欢

转载自blog.csdn.net/weixin_42270645/article/details/123661232