如何在JSON中使用oneOf并结合Jackson、jsonschema2pojo Maven插件生成Java对象并校验
{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "additionalProperties": false, "oneOf":[{"$ref":"request1.json#"},{"$ref":"request2.json#"}] }
完整实现步骤
1. 配置jsonschema2pojo Maven插件
要求插件版本≥1.1.1,该版本开始原生支持oneOf规则的类生成。pom.xml中插件配置参考如下:
<plugin> <groupId>org.jsonschema2pojo</groupId> <artifactId>jsonschema2pojo-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <sourceDirectory>${project.basedir}/src/main/resources/schemas</sourceDirectory> <targetPackage>com.yourpackage.pojo</targetPackage> <includeOneOfInterface>true</includeOneOfInterface> <includeAdditionalProperties>false</includeAdditionalProperties> <useJackson>true</useJackson> </configuration> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin>
配置说明:
includeOneOfInterface设为true后,插件会为oneOf中指定的多个Schema对应的生成类,自动生成一个公共的父接口,根Schema对应的生成类会使用该接口作为字段类型,自动适配Request1、Request2两种结构includeAdditionalProperties设为false,匹配你Schema中additionalProperties=false的规则,生成的POJO不会包含额外字段的存储结构
2. 运行时校验逻辑实现
jsonschema2pojo仅生成POJO结构,不会自动集成oneOf的运行时校验,需要额外搭配JSON Schema校验组件实现,可按以下步骤操作:
- 引入校验依赖:
<dependency> <groupId>com.networknt</groupId> <artifactId>json-schema-validator</artifactId> <version>1.0.87</version> </dependency>
- 编写校验+反序列化工具代码:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; import com.networknt.schema.ValidationMessage; import java.util.Set; public class RequestValidationUtils { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final JsonSchema ROOT_SCHEMA; static { JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); ROOT_SCHEMA = factory.getSchema(RequestValidationUtils.class.getResourceAsStream("/schemas/root-request.json")); } public static <T> T validateAndDeserialize(String jsonStr, Class<T> clazz) throws IllegalArgumentException { try { // 先校验原始JSON匹配Schema规则 JsonNode jsonNode = OBJECT_MAPPER.readTree(jsonStr); Set<ValidationMessage> errors = ROOT_SCHEMA.validate(jsonNode); if (!errors.isEmpty()) { throw new IllegalArgumentException("JSON不符合Schema规则: " + errors); } // 校验通过后再反序列化为目标POJO return OBJECT_MAPPER.treeToValue(jsonNode, clazz); } catch (Exception e) { throw new IllegalArgumentException("请求校验或反序列化失败: " + e.getMessage(), e); } } }
3. 业务使用示例
// 传入请求JSON字符串,直接拿到校验后的POJO RootRequest request = RequestValidationUtils.validateAndDeserialize(requestJson, RootRequest.class); // oneOf对应的字段会自动适配为Request1或Request2的实例 if (request.getPayload() instanceof Request1) { // 处理Request1逻辑 } else if (request.getPayload() instanceof Request2) { // 处理Request2逻辑 }
内容的提问来源于stack exchange,提问作者raqm
相关产品推荐
相关产品推荐

