# 配置--0.断言工厂

# 内置断言工厂

https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/request-predicates-factories.html#path-route-predicate-factory

# After

日期时间(Java 的 ZonedDateTime 类型)。该断言匹配发生在指定日期时间之后的所有请求。以下是一个配置 After route 谓词的示例:

Example 1. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2024-01-11T17:11:15.438+08:00[Asia/Shanghai]

# Before

Example 2. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

# Between

Example 3. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

接收两个参数:cookie名称和正则表达式(Java正则表达式)。 匹配具有给定名称且值与正则表达式匹配的cookie。 以下是一个配置cookie路由示例

Example 4. application.yml

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

the header name and a regexp (which is a Java regular expression).

Example 5. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

# Host

Example 6. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

# Method

Example 7. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

# Path

路由Path断言工厂采用两个参数:一个 Spring 列表PathMatcher patterns和一个名为 的可选标志matchTrailingSlash(默认为true)。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

如果请求路径是,则此路由匹配,例如:/red/1or /red/1/or /red/blueor /blue/green

If matchTrailingSlash is set to false, then request path /red/1/ will not be matched.

# Query

a required param and an optional regexp (which is a Java regular expression).

Example 9. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green

The preceding route matches if the request contained a green query parameter.

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.

The preceding route matches if the request contained a red query parameter whose value matched the gree. regexp, so green and greet would match.

# RemoteAddr

The RemoteAddr route predicate factory takes a list (min size 1) of sources, which are CIDR-notation (IPv4 or IPv6) strings, such as 192.168.0.1/16 (where 192.168.0.1 is an IP address and 16 is a subnet mask). The following example configures a RemoteAddr route predicate:

Example 10. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

# Weight

group and weight (an int). The weights are calculated per group.

Example 11. application.yml

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

This route would forward ~80% of traffic to weighthigh.org (opens new window) and ~20% of traffic to weighlow.org (opens new window)

# 自定义断言工厂

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

1、spring的bean

2、后缀RoutePredicateFactory

3、继承AbstractRoutePredicateFactory

4、提供静态内部类Config

5、结合shortcutFieldOrder数据绑定

6、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 
更新时间: 2024年1月15日星期一晚上7点55分