Gateway Predicate断言(谓词)

是什么

Spring Cloud Gateway匹配路由作为Spring WebFlux HandlerMapping基础设施的一部分。 Spring Cloud Gateway包含许多内置的路由谓词工厂。 所有这些谓词都匹配HTTP请求的不同属性。 您可以使用逻辑 and 语句来联合收割机组合多个路由谓词工厂。

Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理。

分类

                                                

idea启动项目打印的日志: 

常用的内置Route Predicate

id:我们自定义的路由 ID,保持唯一
uri:目标服务地址
predicates:路由条件,Predicate接受一个输入参数返回一个布尔值。
        该属性包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)

配置语法总体概述

2种配置方式,二选一

短格式配置

完全展开配置

测试地址

http://localhost:9527/pay/gateway/get/1

After Route Predicate

After路由谓词工厂接受一个datetime参数(这是一个java ZonedDateTime)。

在指定日期时间之后才可以请求该地址。

spring:
  cloud:
    gateway:
      routes:
        - id: after_route
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - After=2024-04-24T23:56:23.970133500+08:00[Asia/Shanghai]

如何获取ZonedDateTime

import java.time.ZonedDateTime;

public class Testtt {
    public static void main(String[] args) {
        ZonedDateTime zonedDateTime = ZonedDateTime.now().plusMinutes(1);   // 1分钟之后的时间
        System.out.println(zonedDateTime);
    }
}

Before Route Predicate

Before路由谓词工厂接受一个datetime参数(这是一个java ZonedDateTime)。

在指定日期时间之前才可以请求该地址。

spring:
  cloud:
    gateway:
      routes:
        - id: before_route
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Before=2024-04-25T00:02:10.783066100+08:00[Asia/Shanghai]

Between Route Predicate

Between路由谓词工厂接受两个参数,datetime1和datetime2(都是Java ZonedDateTime)。用英文逗号分隔。

在datetime1之后和datetime2之前可以请求该地址。

datetime2参数必须在datetime1之后。

spring:
  cloud:
    gateway:
      routes:
        - id: between_route
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Between=2024-04-24T23:56:23.970133500+08:00[Asia/Shanghai], 2024-04-25T00:02:10.783066100+08:00[Asia/Shanghai]

Cookie Route Predicate

Cookie Route Predicate需要两个参数,一个是 Cookie name ,一个是正则表达式。
路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

spring:
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Cookie=chocolate, ch.p

Header Route Predicate

Header路由谓词工厂接受两个参数,header和regexp(这是一个Java正则表达式)。

此谓词与具有给定名称且其值与正则表达式匹配的标头匹配。

spring:
  cloud:
        service-name: ${spring.application.name}
    gateway:
      routes:
        - id: header_route
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Header=X-Request-Id, [0-9]+

Host Route Predicate

Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。

它通过参数中的主机地址作为匹配规则。

spring:
  cloud:
    gateway:
      routes:
        - id: pay_routh1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Host=**.somehost.org,**.anotherhost.org

Path Route Predicate

路径相匹配的进行路由

spring:
  cloud:
    gateway:
      routes:
        - id: pay_routh1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**

Query Route Predica

Query路由谓词工厂有两个参数:一个必需的param和一个可选的regexp(这是一个Java正则表达式)。

请求包含param查询参数。

spring:
  cloud:
    gateway:
      routes:
        - id: pay_routh1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Query=green

RemoteAddr route predicate

RemoteAddr路由断言工厂采用sources的列表(最小大小为1),这些列表是CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。

什么是计算机网络中的 CIDR

spring:
  cloud:
    gateway:
      routes:
        - id: pay_routh1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - RemoteAddr=192.168.31.171/24

Method Route Predicat

Method路由谓词工厂接受一个methods参数,它是一个或多个参数:要匹配的HTTP方法。

配置某个请求地址,只能用Get/Post方法访问,方法限制。

spring:
  cloud:
    gateway:
      routes:
        - id: pay_routh1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - Method=GET,POST

Weight Route Predicat

Weight路由谓词工厂有两个参数:group和weight(一个int)。计算每组的权重。 

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

该路由将把80%的流量转发到weightthigh.org,20%的流量转发到weightlow.org。

自定义断言

规则:

        要么继承AbstractRoutePredicateFactory抽象类

        要么实现RoutePredicateFactory接口

        开头任意取名,但是必须以RoutePredicateFactory后缀结尾

仿照:AfterRoutePredicateFactory

自定义XXXRoutePredicateFactory

1. 新建类名XXX需要以RoutePredicateFactory结尾,并继承AbstractRoutePredicateFactory类。

2. 重写apply方法

3. 新建apply方法所需要的静态内部类MyRoutePredicateFactory.Config,这个Config类就是我们的路由断言规则,重要

4. 空参构造方法,内部调用super

5. 重载 shortcutFieldOrder 方法

        不重载,配置的时候只能完全展开配置,不能短格式配置。

package com.yq.springcloud.predicate;

import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

    public static final String PARAM_USERTYPE = "userType";

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

    /**
     * 返回有关参数数和快捷方式分析顺序的提示
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList(PARAM_USERTYPE);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return serverWebExchange -> {
            //检查request的参数里面,userType是否为指定的值,符合配置就通过
            String userType = serverWebExchange.getRequest().getQueryParams().getFirst(PARAM_USERTYPE);

            if (userType == null) return false;

            //如果说参数存在,就和config的数据进行比较
            if (userType.equals(config.getUserType())) {
                return true;
            }
            return false;
        };
    }

    @Validated
    @Data
    public static class Config {
        @NotBlank
        private String userType; //钻、金、银等用户等级
    }
}

自定义GatewayAutoConfiguration

仿照:org.springframework.cloud.gateway.config.GatewayAutoConfiguration

将自己自定义的断言加入IOC

package com.yq.springcloud.config;

import com.yq.springcloud.predicate.MyRoutePredicateFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration;
import org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration;
import org.springframework.cloud.gateway.config.conditional.ConditionalOnEnabledPredicate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class,
        GatewayClassPathWarningAutoConfiguration.class })
public class MyGatewayAutoConfiguration {

    @Bean
    @ConditionalOnEnabledPredicate
    public MyRoutePredicateFactory myRoutePredicateFactory() {
        return new MyRoutePredicateFactory();
    }
}

 配置文件中添加配置断言

spring:
  cloud:
    gateway:
      routes:
        - id: pay_routh1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/pay/gateway/get/**
            - My=diamond

测试

1, 启动的时候,已加载到断言中

2. 只有userType=diamond才可以正常访问。

相关推荐

  1. Gateway路由谓词断言)功能

    2024-05-01 06:08:04       19 阅读
  2. HIVE:谓词下推

    2024-05-01 06:08:04       10 阅读
  3. 断言assert

    2024-05-01 06:08:04       31 阅读
  4. postman断言

    2024-05-01 06:08:04       31 阅读
  5. Python断言

    2024-05-01 06:08:04       22 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-01 06:08:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-01 06:08:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-01 06:08:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-01 06:08:04       20 阅读

热门阅读

  1. 如何使用dlib库进行目标跟踪

    2024-05-01 06:08:04       12 阅读
  2. MATLAB初学者入门(28)—— 有监督学习神经网络

    2024-05-01 06:08:04       10 阅读
  3. 深入探索HTML与CSS:构建网页的基础

    2024-05-01 06:08:04       10 阅读
  4. MATLAB初学者入门(27)—— 无监督学习神经网络

    2024-05-01 06:08:04       11 阅读
  5. 云原生周刊:K8s 中的服务和网络 | 2024.4.29

    2024-05-01 06:08:04       19 阅读
  6. Mysql MVVC

    2024-05-01 06:08:04       11 阅读
  7. CSS三个标题及对应内容的tab切换

    2024-05-01 06:08:04       10 阅读
  8. python挑战10秒小程序

    2024-05-01 06:08:04       8 阅读