gataway断言源码剖析

简介: gataway断言源码剖析

Cookie断言来说,首先看它的体系结构

public class CookieRoutePredicateFactory
        extends AbstractRoutePredicateFactory<CookieRoutePredicateFactory.Config> {
    /**
     * Name key.
     */
    public static final String NAME_KEY = "name";
    /**
     * Regexp key.
     */
    public static final String REGEXP_KEY = "regexp";
    public CookieRoutePredicateFactory() {
        super(Config.class);
    }
    /*
      通过shortcutFieldOrder方法设置Config配置类中的属性,需要根据具体的规则来设置
      通过shortcutType方法获取具体规则,具体参看:org.springframework.cloud.gateway.support.ShortcutConfigurable.ShortcutType
      规则包括以下几种:
        DEFAULT : 按照shortcutFieldOrder顺序依次赋值
    */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(NAME_KEY, REGEXP_KEY);
    }
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                List<HttpCookie> cookies = exchange.getRequest().getCookies()
                        .get(config.name);
                if (cookies == null) {
                    return false;
                }
                for (HttpCookie cookie : cookies) {
                    if (cookie.getValue().matches(config.regexp)) {
                        return true;
                    }
                }
                return false;
            }
            @Override
            public String toString() {
                return String.format("Cookie: name=%s regexp=%s", config.name,
                        config.regexp);
            }
        };
    }
    /*
     内部配置类是用来接收在配置文件中配置的参数的
      routes:
        #唯一标识符
        - id: hailtaxi-driver
          uri: lb://hailtaxi-driver
          #路由断言
          predicates:
            - Cookie=username,itheima
    */
    @Validated
    public static class Config {
        @NotEmpty
        private String name;
        @NotEmpty
        private String regexp;
        public String getName() {
            return name;
        }
        public Config setName(String name) {
            this.name = name;
            return this;
        }
        public String getRegexp() {
            return regexp;
        }
        public Config setRegexp(String regexp) {
            this.regexp = regexp;
            return this;
        }
    }
}

尽管Spring Cloud Gateway已经包含了很多路由匹配规则,有时候我们需要开发自定义路由匹配规则来满足需求,下面简单的介绍一下如何自定义路由匹配规则。

案例

需求:转发带token的请求到hailtaxi-drvier服务中,这里定义请求带token是指包含某个请求头的请求,至于是什么请求头可以由配置指定

1、修改配置文件

gateway:
      #路由配置
      routes:
        #唯一标识符
        - id: hailtaxi-driver
          uri: lb://hailtaxi-driver
          #路由断言
          predicates:
            # 自定义一个Token断言,如果请求包含Authorization的token信息则通过
            - Token=Authorization

2、创建 RoutePredicateFactory

断言工厂默认命名规则必须按照"名称"+RoutePredicateFactory,如上TokenRoutePredicateFactory的断言名称为Token

@Slf4j
@Component // 要交给spring容器管理
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenRoutePredicateFactory.Config> {
    public TokenRoutePredicateFactory() {
        super(Config.class);
    }
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            // 打印配置文件参数值
            String headerName = config.getHeaderName();
            HttpHeaders headers = exchange.getRequest().getHeaders();
            List<String> header = headers.get(headerName);
            log.info("Token Predicate headers:{}", header);
            // 断言返回的是boolean值
            return header!=null && header.size()>0;
        };
    }
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("headerName");//指定配置文件中加载到的配置信息应填充到Config的哪个属性上
    }
    @Override
    public ShortcutType shortcutType() {
        return ShortcutType.DEFAULT;
    }
    @Data
    public static class Config { //static class
        private String headerName;//存储从配置文件中加载的配置
    }
}

启动测试:http://localhost:8001/driver/info/1

相关文章
|
7月前
|
程序员 编译器 C++
【实用编程技巧】不想改bug?初学者必须学会使用的报错函数assert!(断言函数详解)
【实用编程技巧】不想改bug?初学者必须学会使用的报错函数assert!(断言函数详解)
68 2
|
2月前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
69 1
|
4月前
一文搞懂正则表达式之零宽断言
零宽断言: 用于查找在某些内容之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
196 0
一文搞懂正则表达式之零宽断言
|
测试技术
测试中进行断言是什么意思?底层原理是什么?
测试中进行断言是什么意思?底层原理是什么?
1444 0
|
Java 容器
sprigboot中过滤器执行顺序源码解读
本文主要是搞清楚对于同一请求在springboot项目中自定义的filter和jar包中的filter的执行顺序是如何指定的。
sprigboot中过滤器执行顺序源码解读
|
Go C语言
嵌入式C语言基础之断言
嵌入式C语言基础之断言
142 0
|
前端开发
先行断言(lookahead)和后行断言(lookbehind)
先行断言(lookahead)和后行断言(lookbehind)
140 0
|
缓存 Java Spring
千万别再卷Spring循环依赖了,这篇文章一定让你搞清楚
4.1 满足循环依赖的条件是什么? 必须是单例模式 循环依赖类,必须能实例化(空构造,或构造参数满足循环依赖条件) 4.2 循环依赖可能导致什么问题? 在执行初始化的时候,如果初始化方法,依赖循环来的属性注入参数,可能导致获取不到数据信息的情况如上面问题1。 4.3 为什么要用三级缓存而不是二级缓存? 为了满足Spring声明周期方法,即对半成品的B进行提前生命周期处理。如实现AOP.
184 0
|
网络协议 测试技术 Go
类型断言引出和基本使用|学习笔记
快速学习类型断言引出和基本使用
|
Java
JavaSE面试题03:方法的参数传递机制
JavaSE面试题03:方法的参数传递机制
87 0