Spring GateWay中,DefaultFilter和GlobalFilter的区别

在Spring Cloud Gateway中,DefaultFilter和GlobalFilter都是用于执行请求过滤逻辑的接口,但它们的作用有些不同。

DefaultFilter是一种内置的过滤器类型,用于实现GatewayFilter接口的默认实现,提供了一些通用的过滤逻辑,例如请求/响应日志记录、路由信息记录等。可以通过配置来自定义和覆盖DefaultFilter的行为。

GlobalFilter则是一种自定义的过滤器类型,它可以被应用于全局的请求过滤链中,无需显式地将其添加到路由规则中。GlobalFilter在请求被路由之前和之后都会被执行,并且可以对请求和响应进行修改。通常情况下,GlobalFilter用于实现一些通用的逻辑,例如身份认证、请求限流、请求日志记录等。

因此,可以认为DefaultFilter是Spring Cloud Gateway中内置的一些通用过滤器的实现,而GlobalFilter则是用户可以自定义的全局过滤器,用于实现一些通用的业务逻辑。在实际使用中,可以根据具体的需求选择合适的过滤器类型来实现请求过滤逻辑。‘

以下是一些示例,说明在不同场景下,如何使用DefaultFilter和GlobalFilter来实现请求过滤逻辑:

1、日志记录

使用DefaultFilter实现:在application.yml配置文件中,可以使用以下配置来启用请求日志记录:

spring:
  cloud:
    gateway:
      httpclient:
        wiretap: true
      default-filters:
      - name: RequestTimeFilter
        args:
          baseMessageData: true
          inClass: java.lang.Object
          outClass: java.lang.Object

这里配置了一个名为RequestTimeFilter的DefaultFilter,它将记录请求的时间信息,并在请求完成时将其输出到日志中。

使用GlobalFilter实现:定义一个实现了GlobalFilter接口的过滤器类,重写filter方法,在该方法中实现请求日志记录的逻辑,例如:

@Component
public class RequestLoggingFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long startTime = System.currentTimeMillis();

        return chain.filter(exchange).doFinally(signalType -> {
            long endTime = System.currentTimeMillis();
            long executeTime = endTime - startTime;

            String path = exchange.getRequest().getPath().toString();
            String method = exchange.getRequest().getMethodValue();
            int status = exchange.getResponse().getStatusCode().value();

            // 日志输出逻辑
            log.info("Request [{} {}] finished with status [{}] in [{}] ms", method, path, status, executeTime);
        });
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

这里定义了一个RequestLoggingFilter类,它实现了GlobalFilter接口,并重写了filter方法,在该方法中实现了请求日志记录的逻辑。通过实现GlobalFilter接口,并将过滤器添加到Spring容器中,就可以实现全局的请求日志记录。

2、身份认证

使用GlobalFilter实现:定义一个实现了GlobalFilter接口的过滤器类,重写filter方法,在该方法中实现身份认证的逻辑,例如:

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");

        if (StringUtils.isEmpty(token)) {
            return unauthorized(exchange);
        }

        // 调用身份认证服务进行认证
        boolean isValidToken = authenticate(token);

        if (!isValidToken) {
            return unauthorized(exchange);
        }

        return chain.filter(exchange);
    }

    private Mono<Void> unauthorized(ServerWebExchange exchange) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }

    private boolean authenticate(String token) {
        // 调用身份认证服务进行认证,返回认证结果
        return true;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

这里定义了一个AuthFilter类,它实现了GlobalFilter接口,并重写了filter方法,在该方法中实现了身份认证的逻辑。在该方法中,我们从请求头中获取认证令牌,然后调用身份认证服务进行认证,最后根

据认证结果决定是否允许请求通过。如果认证失败,就返回HTTP状态码为401(未授权)的响应,否则将请求转发给下一个过滤器或者目标服务。

可以将AuthFilter添加到Spring容器中,以便全局使用。

3、请求限流

使用GlobalFilter实现:定义一个实现了GlobalFilter接口的过滤器类,重写filter方法,在该方法中实现请求限流的逻辑,例如:

@Component
public class RateLimitFilter implements GlobalFilter, Ordered {

    private final RateLimiter rateLimiter;

    public RateLimitFilter(RateLimiter rateLimiter) {
        this.rateLimiter = rateLimiter;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String key = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
        RateLimiter.Response response = rateLimiter.isAllowed(key);

        if (response.isAllowed()) {
            return chain.filter(exchange);
        } else {
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }
    }

    @Override
    public int getOrder() {
        return -2;
    }
}

这里定义了一个RateLimitFilter类,它实现了GlobalFilter接口,并重写了filter方法,在该方法中实现了请求限流的逻辑。在该方法中,我们从请求中获取客户端的IP地址,并使用一个名为RateLimiter的限流工具对请求进行限流。如果请求被允许通过,就将请求转发给下一个过滤器或者目标服务,否则返回HTTP状态码为429(太多请求)的响应。

在实际使用中,可以将RateLimitFilter添加到Spring容器中,以便全局使用。同时,也可以根据具体的需求,将不同的限流规则应用于不同的路由规则或服务实例。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值