一、背景介绍

在微服务架构里,网关是系统的重要入口,能处理很多事情,像请求路由、安全认证、限流这些。不过,参数验证和清洗也是很关键的步骤,要是能统一在网关层实现,就能让系统的结构更清晰,代码也更好维护。下面就来讲讲基于自定义 GlobalFilter 与验证器链的 Spring Cloud Gateway 方案。

二、Spring Cloud Gateway 基础

2.1 Spring Cloud Gateway 简介

Spring Cloud Gateway 是 Spring Cloud 里的一个 API 网关,能帮我们实现路由、过滤这些功能。它基于 Spring WebFlux 构建,有异步非阻塞的特性,性能很不错。

2.2 Gateway 核心组件

Gateway 里主要有路由(Route)、断言(Predicate)和过滤器(Filter)这几个核心组件。路由就是把请求映射到目标服务;断言用来判断请求是否符合条件;过滤器则能在请求处理前后做一些操作。

三、参数验证与清洗的重要性

3.1 防止非法请求

在实际应用中,会收到各种各样的请求,有些可能是恶意的或者不符合要求的。通过参数验证,可以过滤掉这些非法请求,保证系统的安全和稳定。

3.2 提高数据质量

参数清洗能把请求中的一些无效数据、格式错误的数据处理掉,让进入系统的数据质量更高,减少后续处理的麻烦。

四、自定义 GlobalFilter 实现

4.1 创建自定义 GlobalFilter

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

// 自定义 GlobalFilter 类
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求
        ServerHttpRequest request = exchange.getRequest();
        // 这里可以进行参数验证和清洗
        System.out.println("进行参数验证和清洗操作");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        // 设置过滤器的执行顺序
        return 1;
    }
}

这个自定义的 GlobalFilter 实现了 GlobalFilterOrdered 接口。filter 方法里可以进行参数验证和清洗的操作,getOrder 方法用来设置过滤器的执行顺序。

4.2 配置自定义 GlobalFilter

在配置文件里不需要额外配置,因为 Spring 会自动扫描并注册 @Component 注解的类。

五、验证器链的设计与实现

5.1 验证器接口定义

// 验证器接口
public interface Validator {
    // 验证方法
    boolean validate(Object param);
}

这个接口定义了一个 validate 方法,用来对参数进行验证。

5.2 具体验证器实现

// 具体的验证器实现类
public class LengthValidator implements Validator {
    private int minLength;
    private int maxLength;

    public LengthValidator(int minLength, int maxLength) {
        this.minLength = minLength;
        this.maxLength = maxLength;
    }

    @Override
    public boolean validate(Object param) {
        if (param instanceof String) {
            String str = (String) param;
            return str.length() >= minLength && str.length() <= maxLength;
        }
        return false;
    }
}

这个 LengthValidator 类实现了 Validator 接口,用来验证字符串的长度是否在指定范围内。

5.3 验证器链实现

import java.util.ArrayList;
import java.util.List;

// 验证器链类
public class ValidatorChain {
    private List<Validator> validators = new ArrayList<>();

    // 添加验证器到链中
    public ValidatorChain addValidator(Validator validator) {
        validators.add(validator);
        return this;
    }

    // 执行验证
    public boolean validate(Object param) {
        for (Validator validator : validators) {
            if (!validator.validate(param)) {
                return false;
            }
        }
        return true;
    }
}

ValidatorChain 类用来管理验证器,通过 addValidator 方法可以添加验证器,validate 方法会依次调用链中的验证器进行验证。

六、将验证器链集成到 GlobalFilter 中

6.1 修改 CustomGlobalFilter

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        // 获取请求参数
        String param = request.getQueryParams().getFirst("param");
        // 创建验证器链
        ValidatorChain validatorChain = new ValidatorChain();
        // 添加验证器
        validatorChain.addValidator(new LengthValidator(3, 10));
        // 进行验证
        if (!validatorChain.validate(param)) {
            // 验证不通过,返回错误信息
            System.out.println("参数验证不通过");
            return Mono.empty();
        }
        return chain.filter(exchange);
    }

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

CustomGlobalFilter 里,获取请求参数,创建验证器链,添加验证器并进行验证。如果验证不通过,就返回错误信息。

七、应用场景

7.1 电商系统

在电商系统里,用户下单时会提交很多参数,像商品数量、收货地址这些。在网关层进行参数验证和清洗,可以防止用户输入非法的商品数量,或者过滤掉格式错误的收货地址。

7.2 社交系统

社交系统中,用户注册和登录时会提交用户名、密码等信息。通过网关层的参数验证,可以保证用户名和密码的格式符合要求,提高系统的安全性。

八、技术优缺点

8.1 优点

  • 统一管理:把参数验证和清洗统一在网关层,能让代码更集中,方便管理和维护。
  • 提高性能:在网关层就过滤掉非法请求,减少了后端服务的压力,提高了系统的整体性能。
  • 可扩展性:通过验证器链的设计,可以很方便地添加新的验证器,满足不同的验证需求。

8.2 缺点

  • 单点故障:如果网关出现问题,整个系统可能会受到影响。
  • 增加网关负担:参数验证和清洗会增加网关的处理负担,如果请求量很大,可能会影响网关的性能。

九、注意事项

9.1 性能优化

在进行参数验证和清洗时,要注意性能优化。可以采用异步处理的方式,减少阻塞时间。

9.2 异常处理

要对验证过程中可能出现的异常进行处理,避免因为异常导致系统崩溃。

9.3 配置管理

验证规则和配置要进行合理的管理,方便修改和扩展。

十、文章总结

通过自定义 GlobalFilter 和验证器链,我们可以在 Spring Cloud Gateway 中实现参数验证和清洗的统一处理。这种方案能让系统结构更清晰,提高数据质量和系统安全性。不过,在使用过程中要注意性能优化、异常处理和配置管理等问题。