Gateway Cookie 路由断言工厂

Cookie 路由断言工厂需要两个参数,分别是 Cookie name 和 regexp(Java 正则表达式)。语法如下:

Cookie=Cookie名称, Cookie的值

该断言会匹配具有给定 name 并且其值符合 regexp 正则表达式的 cookie。例如:

spring:
 cloud:
   gateway:
     routes:
     - id: cookie_route
       uri: https://example.org
       predicates:
       - Cookie=chocolate, ch.p

上面的配置,cookie_route 路由会匹配 cookie 名为 chocolate 并且其值符合 ch.p 正则表达式的请求。注意,正则表达式中 “.” 表示任意字符,因此可以匹配 chap、chwp、……等等。

示例

将“Gateway 搭建网关服务”项目的配置文件 bootstrap.yml 内容使用如下配置替换:

server:
  # 网关端口
  port: 9000

spring:
  application:
    # 服务名称
    name: gateway-demo01
  cloud:
    # nacos
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        group: DEFAULT_GROUP

    # 网关路由配置
    gateway:
      # 网关路由配置
      routes:
        # 路由id,自定义,只要唯一集合
        - id: service-order
          # 路由的目标地址,lb 就是负载均衡,后面跟服务名
          # 需要集成 nacos 等服务注册中心
          uri: lb://service-order
          # 路由断言,也就是判断请求是否符合路由规则的条件
          predicates:
            # Cookie断言:匹配名为 my_cookie,值为 www.hxstrive.com,其中 www 可以为任何 a-zA-Z0-9 多个字符
            - Cookie=my_cookie, [a-zA-Z0-9]+\.hxstrive\.com

重启网关服务,使用 Postman 访问订单接口(注意,需要添加一个名为 my_cookit 的 Cookie),如下图:

Gateway Cookie 路由断言工厂

Gateway Cookie 路由断言工厂

从上图可知,成功请求接口,这是因为添加了一个名为 my_cookie,值为 www.hxstrive.com 的 Cookie。如果我们不传递该 Cookie,则请求将返回 404,如下图:

Gateway Cookie 路由断言工厂

源码分析

下面是 Cookie 路由断言工厂的源码:

package org.springframework.cloud.gateway.handler.predicate;

//...

public class CookieRoutePredicateFactory extends AbstractRoutePredicateFactory<CookieRoutePredicateFactory.Config> {

    public static final String NAME_KEY = "name";
    public static final String REGEXP_KEY = "regexp";

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

    @Override
    public List<String> shortcutFieldOrder() {
       return Arrays.asList(NAME_KEY, REGEXP_KEY);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
       return exchange -> {
          // 从请求中获取指定名称的所有 cookie
          List<HttpCookie> cookies = exchange.getRequest().getCookies().get(config.name);
          
          // 如果没有 cookie,则返回 false
          if (cookies == null) {
             return false;
          }
          
          // 循环判断 cookie,任何一个 cookie 匹配,则返回 true
          for (HttpCookie cookie : cookies) {
             if (cookie.getValue().matches(config.regexp)) {
                return true;
             }
          }
          return false;
       };
    }

    @Validated
    public static class Config {
       // cookie 名称
       @NotEmpty
       private String name;
       // 匹配值的正则表达式
       @NotEmpty
       private String regexp;

       // 配置信息
    }
}

说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号