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

如何使用RESTeasy和Jackson通过JSON Schema验证JSON数据?

基于JBoss EAP 7 + RESTeasy的JSON Schema验证方案

结合你的技术栈,下面提供两种可行的JSON Schema验证实现方式,均基于你已生成的openapi.json文件:

方式一:自定义RESTeasy过滤器 + NetworkNT JSON Schema验证库

这种方式灵活性高,可精确控制验证逻辑,适配所有JBoss EAP 7版本。

1. 添加依赖

在pom.xml中引入JSON Schema验证相关依赖:

<dependency>
    <groupId>com.networknt</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>1.0.89</version>
</dependency>
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.8.0</version>
</dependency>

2. 编写验证过滤器

创建全局请求过滤器,自动加载openapi.json并验证接口请求体:

import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;
import com.jayway.jsonpath.JsonPath;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider;
import org.jboss.resteasy.core.ResourceMethodInvoker;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Set;

@Provider
public class OpenApiSchemaValidationFilter implements ContainerRequestFilter {

    private final String openApiJson;
    private final JsonSchemaFactory schemaFactory;

    public OpenApiSchemaValidationFilter() {
        // 从classpath加载生成的openapi.json
        try (InputStream is = getClass().getClassLoader().getResourceAsStream("openapi.json")) {
            openApiJson = new String(is.readAllBytes(), StandardCharsets.UTF_8);
            schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
        } catch (Exception e) {
            throw new RuntimeException("加载OpenAPI Schema失败", e);
        }
    }

    @Override
    public void filter(ContainerRequestContext requestContext) {
        // 仅处理JSON类型请求
        if (!requestContext.getMediaType().isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
            return;
        }

        // 获取当前调用的资源方法信息
        ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) requestContext.getProperty(
                "org.jboss.resteasy.core.ResourceMethodInvoker");
        if (methodInvoker == null) {
            return;
        }

        // 拼接完整接口路径(资源类Path + 方法Path)
        String basePath = methodInvoker.getResourceClass().getAnnotation(jakarta.ws.rs.Path.class).value();
        String methodPath = methodInvoker.getMethod().getAnnotation(jakarta.ws.rs.Path.class).value();
        String fullPath = basePath + methodPath;
        String httpMethod = requestContext.getMethod();

        try {
            // 从OpenAPI文档中提取对应接口的请求体Schema
            String refPath = JsonPath.read(openApiJson, 
                    "$.paths['" + fullPath + "']." + httpMethod.toLowerCase() + ".requestBody.content['application/json'].schema.$ref");
            String schemaJson = JsonPath.read(openApiJson, refPath.replace("#", "$"));
            
            // 初始化Schema验证器
            JsonSchema schema = schemaFactory.getSchema(schemaJson);
            
            // 读取并重置请求体流(避免后续处理丢失数据)
            byte[] bodyBytes = requestContext.getEntityStream().readAllBytes();
            requestContext.setEntityStream(new java.io.ByteArrayInputStream(bodyBytes));
            
            // 解析JSON并执行验证
            com.fasterxml.jackson.databind.JsonNode requestNode = new com.fasterxml.jackson.databind.ObjectMapper().readTree(bodyBytes);
            Set<ValidationMessage> errors = schema.validate(requestNode);
            
            // 验证失败则返回400错误
            if (!errors.isEmpty()) {
                StringBuilder errorMsg = new StringBuilder("JSON Schema验证失败:");
                errors.forEach(msg -> errorMsg.append(msg.getMessage()).append("; "));
                requestContext.abortWith(Response.status(Response.Status.BAD_REQUEST)
                        .entity(errorMsg.toString())
                        .type(MediaType.TEXT_PLAIN)
                        .build());
            }
        } catch (Exception e) {
            // 处理Schema查找或验证异常
            requestContext.abortWith(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                    .entity("请求体验证失败:" + e.getMessage())
                    .type(MediaType.TEXT_PLAIN)
                    .build());
        }
    }
}

3. 启用过滤器

@Provider注解会让RESTeasy自动扫描并注册该过滤器,无需额外配置。如果未自动扫描,可在web.xml中手动注册:

<web-app>
    <context-param>
        <param-name>resteasy.providers</param-name>
        <param-value>com.yourpackage.OpenApiSchemaValidationFilter</param-value>
    </context-param>
</web-app>

方式二:使用Smallrye OpenAPI Validator扩展

如果你的JBoss EAP 7版本为7.4+(支持MicroProfile 4.0+),可直接使用Smallrye官方的验证扩展,配置更简洁。

1. 添加依赖

<dependency>
    <groupId>io.smallrye</groupId>
    <artifactId>smallrye-openapi-validator</artifactId>
    <version>3.2.0</version>
</dependency>

2. 启用验证

在src/main/resources/application.properties中添加配置:

# 启用OpenAPI请求验证
smallrye.openapi.validator.enabled=true
# 可选:验证失败时返回详细错误信息
smallrye.openapi.validator.fail-fast=false

该扩展会自动加载openapi.json,对所有接口的请求体、参数等进行Schema验证,无需编写自定义代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:20:07