You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Cloud Gateway中校验请求体与指定Schema的匹配性?

Spring Cloud Gateway 仅转发符合指定JSON Schema的请求实现方案

核心思路

通过异步Predicate结合JSON Schema校验实现,同时利用Spring官方工具缓存请求体,避免后续转发时请求体丢失,逻辑集中且高效,无需复杂过滤器链。

步骤实现

1. 准备JSON Schema文件

在resources/schema下创建校验规则文件,例如example-schema.json:

{
  "type": "object",
  "required": ["id", "name"],
  "properties": {
    "id": {"type": "integer"},
    "name": {"type": "string", "minLength": 2}
  }
}

2. 引入依赖

添加JSON Schema校验所需依赖到pom.xml:

<dependency>
    <groupId>org.everit.json</groupId>
    <artifactId>org.everit.json.schema</artifactId>
    <version>1.14.0</version>
</dependency>
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230618</version>
</dependency>

3. 编写路由配置

修改你的路由函数,使用asyncPredicate完成异步校验:

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
import reactor.core.publisher.Mono;

import java.io.InputStream;

@Component
public class ValidatedRouteLocator {

    private final Schema requestSchema;

    // 初始化JSON Schema校验规则
    public ValidatedRouteLocator() throws Exception {
        Resource schemaResource = new ClassPathResource("schema/example-schema.json");
        try (InputStream inputStream = schemaResource.getInputStream()) {
            JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
            requestSchema = SchemaLoader.load(rawSchema);
        }
    }

    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("schema_validated_api", spec -> spec
                        // 异步校验请求体是否符合Schema
                        .asyncPredicate(exchange -> {
                            // 跳过非JSON类型请求
                            MediaType contentType = exchange.getRequest().getHeaders().getContentType();
                            if (contentType == null || !contentType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
                                return Mono.just(false);
                            }

                            // 缓存请求体,保证后续转发可读取
                            return ServerWebExchangeUtils.cacheRequestBody(exchange, cachedRequest ->
                                    cachedRequest.getBody()
                                            .aggregate()
                                            .map(this::convertDataBufferToJson)
                                            .map(this::validateAgainstSchema)
                            );
                        })
                        .and()
                        .path("/api/example")
                        .uri("http://SOME_SERVICE")
                )
                .build();
    }

    // 将DataBuffer转换为JSON对象
    private JSONObject convertDataBufferToJson(DataBuffer dataBuffer) {
        byte[] bytes = new byte[dataBuffer.readableByteCount()];
        dataBuffer.read(bytes);
        DataBufferUtils.release(dataBuffer);
        return new JSONObject(new String(bytes));
    }

    // 校验JSON是否符合Schema
    private boolean validateAgainstSchema(JSONObject jsonObject) {
        try {
            requestSchema.validate(jsonObject);
            return true;
        } catch (Exception e) {
            // 校验失败,返回false,请求不会被转发
            return false;
        }
    }
}

关键说明

  • 使用asyncPredicate:适配反应式场景,支持异步校验逻辑,避免阻塞。
  • 请求体缓存:通过ServerWebExchangeUtils.cacheRequestBody处理请求体的重复读取问题,保证校验后转发时请求体可用。
  • 提前过滤非JSON请求:减少无效校验操作,提升性能。

内容的提问来源于stack exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:35:22