Spring Cloud Alibaba学习笔记(19) - Spring Cloud Gateway 自定义过滤器工厂

在前文中,我们介绍了Spring Cloud Gateway内置了一系列的内置过滤器工厂,若Spring Cloud Gateway内置的过滤器工厂无法满足我们的业务需求,那么此时就需要自定义自己的过滤器工厂以实现特定功能。所谓过滤器工厂实际上就是用于创建过滤器实例的,而创建的过滤器实例都实现于GatewayFilter接口。

过滤器生命周期

Gateway以转发请求为边界,分为两个生命周期

  • pre:Gateway转发请求之前
  • post:Gateway转发请求之后

自定义过滤器工厂

继承AbstractGatewayFilterFactory

可参考源码:org.springframework.cloud.gateway.filter.factory.RequestSizeGatewayFilterFactory

配置形式如下:

spring:
  cloud:
   gateway:
    routes:
      filters:
      # 过滤器工厂的名称
      - name: RequestSize
        # 该过滤器工厂的参数
        args:
          maxSize: 500000

继承AbstractNameValueGatewayFilterFactory

可参考源码:org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory

配置形式如下:

spring:
  cloud:
  gateway:
    routes:
      filters:
      # 过滤器工厂的名称及参数以name-value的形式配置
      - AddRequestHeader=S-Header, Bar

PS:AbstractNameValueGatewayFilterFactory继承了AbstractGatewayFilterFactory,所以实际上第二种方式是第一种方式的简化

核心API

  • exchange.getRequest().mutate().xxx:修改request
    *exchange.mutate().xxx:修改exchange
    *chain.filter(exchange):传递给下一个过滤器处理
    *exchange.getResponse():获取响应对象

PS::exchange实际类型为ServerWebExchange,chain实际类型为GatewayFilter

实现自定义过滤器工厂

需求:记录访问日志

自定义过滤器工厂

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            log.info("配置参数:{}, {}", config.getName(), config.getValue());
            ServerHttpRequest request = exchange.getRequest()
                    .mutate().build();
            ServerWebExchange webExchange = exchange.mutate()
                    .request(request)
                    .build();
            return chain.filter(webExchange);
        };
    }
}

添加相关配置

spring:
    gateway:
      discovery:
        locator:
          enabled: false
      routes:
        - id: study
          uri: lb://study01
          predicates:
            - TimeBetween=上午0:00,下午11:59
          filters:
            # 名称必须为过滤器工厂类名的前缀,并且参数只能有两个,因为NameValueConfig里只定义了两个属性
            - PreLog=testName,testValue

PS:

  • 自定义过滤器工厂类时,按照Spring Cloud Stream的约定,类名须为“过滤器名(本文例中:PreLog)” + GatewayFilterFactory

测试结果

2019-10-28 15:05:10.620  INFO 8734 --- [or-http-epoll-2] c.e.gateway.PreLogGatewayFilterFactory   : 配置参数:testName, testValue
posted @ 2019-10-28 18:29  夜的那种黑丶  阅读(1377)  评论(0编辑  收藏  举报