Spring Cloud Gateway 自定义断言以及过滤器

 1.Spring Cloud gateway介绍

Spring Cloud Gateway 是一个基于 Spring Framework 和 Spring Boot 的 API 网关服务,它利用了 Spring WebFlux 来提供响应式非阻塞式Web请求处理能力。它的核心功能是路由,即根据请求的特定规则将请求转发到后端服务,同时提供了一系列跨领域关注点的处理,如安全认证、监控、限流等。Spring Cloud Gateway 还提供了多种内置的 GatewayFilter 工厂,如 AddRequestHeader、AddRequestParameter、CircuitBreaker、RequestRateLimiter 等,用于修改请求和响应、实现断路器功能、限流等。此外,还可以自定义 GatewayFilter 来满足特定的需求。

 2. predicate介绍

简单来说就是路由条件是否满足的判断,如果满足则进入当前定义的路由规则

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

这里以官网的 AfterRoutePredicateFactory 示例解释

及满足请求时间在 2017-01-20T17:42:47.789-07:00[America/Denver] 之后则断言通过 ,请求会到对应的uri 即 https://example.org

所以这里的断言主要是匹配路由规则的

接下来介绍Spring Cloud Gateway 自带的谓词工厂

项目启动时可以看见这些谓词工厂

他们都继承了 AbstractRoutePredicateFactory  又实现了 RoutePredicateFactory 和 ShortcutConfigurable(捷径匹配)

可以查看每个谓词名称都是类名的前几个字这里可以从 源码中看到把RoutePredicateFactory替换为空了,所以注册时是类名的前几个字

//	RoutePredicateFactory
default String name() {
		return NameUtils.normalizeRoutePredicateName(getClass());
	}

// NameUtils
	public static String normalizeRoutePredicateName(Class<? extends RoutePredicateFactory> clazz) {
		return removeGarbage(clazz.getSimpleName().replace(RoutePredicateFactory.class.getSimpleName(), ""));
	}

 这是捷径匹配的配置 主要返回的是配置的名称(通过”,“分开如果有多个)对应的顺序就是对应名称的配置内容

	default List<String> shortcutFieldOrder() {
		return Collections.emptyList();
	}

 断言的匹配规则

	Predicate<ServerWebExchange> apply(C config);

3.filter介绍

同理都继承了 AbstractGatewayFilterFactory 和实现了 GatewayFilterFactory 以及ShortcutConfigurable

其他都差不多,主要重写 apply 把你的自定义过滤规则写清楚就好了

	GatewayFilter apply(C config);

4.自定义工厂

4.1 自定义predicate工厂

这里我写了一个判断请求路径中user 的判断,满足则通过,并且重写了shortcutFieldOrder 来

@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
    private final String USER_KEY = "user";

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

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return serverWebExchange -> {
            if (serverWebExchange.getRequest().getQueryParams().containsKey(USER_KEY)) {
                String user = serverWebExchange.getRequest().getQueryParams().getFirst(USER_KEY);
                return Objects.equals(user, config.getUser());
            }else {
                return false;
            }
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return List.of(USER_KEY);
    }

    @Validated
    public static class Config {
        @Getter
        @Setter
        @NotBlank
        private String user;
    }
}

 查看配置

spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: "factory" # id 不要重复即可
          uri: http://localhost:8080  # 代理地址
          predicates:
#            - My=user   # user=user
            - name: My
              args:
                user: user

既满足请求路径上有?user=user 的请求地址则可以通过当前路由规则请求http://localhost:8080 服务

4.2 自定义filter 工厂

这里也是通过请求参数status 来判断是否返回 若不满足则返回错误请求

@Slf4j
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
    private  final String  STATUS ="status";
    public MyGatewayFilterFactory() {
        super(Config.class);
    }
    @Override
    public List<String> shortcutFieldOrder() {
        return List.of(STATUS);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            log.info("进入自定义过滤器");
            String status = exchange.getRequest().getQueryParams().getFirst(STATUS);
            if (Objects.equals(status, config.getStatus())){
                return chain.filter(exchange);
            }else {
                exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
                return exchange.getResponse().setComplete();
            }

        };
    }

    @Setter
    @Getter
    @Validated
    public static class Config {
        @NotBlank
        private String status;
    }
}

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZLY_2004

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值