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

如何借助JSON Schema反序列化泛型实体及HashMap<String, Object>?

嘿,我来帮你搞定这两个JSON Schema反序列化的问题,分两种场景给你详细说明,附代码示例:

一、借助JSON Schema反序列化泛型实体

要实现泛型实体的反序列化,核心是保留泛型类型信息+用JSON Schema验证输入格式,这里我们结合常用的everit-json-schema验证库和Jackson序列化库来实现:

步骤说明

  1. 定义你的泛型实体类
  2. 编写对应泛型实例的JSON Schema
  3. 先验证JSON是否符合Schema约束
  4. 用Jackson的TypeReference指定泛型具体类型完成反序列化

代码示例

1. 泛型实体类

public class GenericEntity<T> {
    private String id;
    private T data;

    // 生成getter、setter和构造方法
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public T getData() { return data; }
    public void setData(T data) { this.data = data; }
}

2. JSON Schema文件(比如generic-entity-schema.json)

假设我们要反序列化为GenericEntity<Date>,Schema约束日期字段为ISO 8601格式:

{
  "type": "object",
  "properties": {
    "id": {"type": "string"},
    "data": {"type": "string", "format": "date-time"}
  },
  "required": ["id", "data"]
}

3. 反序列化实现代码

import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;

public class GenericDeserializationDemo {
    public static void main(String[] args) throws Exception {
        // 加载JSON Schema
        JSONObject schemaJson = new JSONObject(new JSONTokener(
                GenericDeserializationDemo.class.getResourceAsStream("/generic-entity-schema.json")
        ));
        Schema schema = SchemaLoader.load(schemaJson);

        // 待处理的JSON字符串
        String jsonInput = "{\"id\":\"user_001\",\"data\":\"2024-05-20T14:30:00Z\"}";
        JSONObject jsonObject = new JSONObject(jsonInput);

        // 第一步:验证JSON是否符合Schema规则
        schema.validate(jsonObject);

        // 第二步:反序列化为泛型实体,用TypeReference保留泛型信息
        ObjectMapper objectMapper = new ObjectMapper();
        // 自动注册日期解析模块,确保日期字符串转成Date类型
        objectMapper.findAndRegisterModules();
        
        GenericEntity<Date> entity = objectMapper.readValue(
                jsonInput,
                new TypeReference<GenericEntity<Date>>() {}
        );

        // 验证类型:输出class java.util.Date
        System.out.println("Data字段类型:" + entity.getData().getClass());
    }
}
二、使用JSON Schema反序列化HashMap<String, Object>(含日期转Date类型)

默认情况下,Jackson会把JSON里的日期字符串转成String类型,要让它自动转成Date,需要配置ObjectMapper的日期解析规则,同时用JSON Schema确保输入格式合法:

步骤说明

  1. 编写约束HashMap结构的JSON Schema(指定日期字段的格式)
  2. 配置ObjectMapper,使其自动识别日期格式并转为Date
  3. 先验证JSON,再反序列化为HashMap

代码示例

1. JSON Schema文件(比如hashmap-schema.json)

{
  "type": "object",
  "properties": {
    "productName": {"type": "string"},
    "launchTime": {"type": "string", "format": "date-time"},
    "stockCount": {"type": "integer"}
  },
  "required": ["productName", "launchTime", "stockCount"]
}

2. 反序列化实现代码

import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import java.util.HashMap;
import java.util.Date;

public class HashMapDeserializationDemo {
    public static void main(String[] args) throws Exception {
        // 加载JSON Schema
        JSONObject schemaJson = new JSONObject(new JSONTokener(
                HashMapDeserializationDemo.class.getResourceAsStream("/hashmap-schema.json")
        ));
        Schema schema = SchemaLoader.load(schemaJson);

        // 待处理的JSON字符串
        String jsonInput = "{\"productName\":\"PhoneX\",\"launchTime\":\"2024-06-01T00:00:00Z\",\"stockCount\":500}";
        JSONObject jsonObject = new JSONObject(jsonInput);

        // 验证JSON格式符合Schema
        schema.validate(jsonObject);

        // 配置ObjectMapper:处理日期转Date,忽略未知字段(可选)
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 自动注册日期解析模块,支持ISO 8601格式转Date
        objectMapper.findAndRegisterModules();

        // 反序列化为HashMap<String, Object>
        HashMap<String, Object> resultMap = objectMapper.readValue(
                jsonInput,
                new TypeReference<HashMap<String, Object>>() {}
        );

        // 验证类型
        System.out.println("launchTime类型:" + resultMap.get("launchTime").getClass()); // 输出class java.util.Date
        System.out.println("stockCount类型:" + resultMap.get("stockCount").getClass()); // 输出class java.lang.Integer
    }
}

关键注意点

  • 依赖准备:确保项目中引入了everit-json-schema和Jackson的核心依赖(Maven示例):
    <dependencies>
        <dependency>
            <groupId>org.everit.json</groupId>
            <artifactId>org.everit.json.schema</artifactId>
            <version>1.14.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.2</version>
        </dependency>
    </dependencies>
    
  • 日期格式自定义:如果你的日期不是ISO 8601格式,可以通过objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))指定自定义格式。
  • 泛型类型保留:不管是泛型实体还是HashMap,都要用TypeReference来指定类型,避免Java类型擦除导致的泛型信息丢失。

内容的提问来源于stack exchange,提问作者Jéssica Miller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:25:46