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

如何使用Jackson按JSON类型解析对象,反序列化不同结构的data字段

实现方案

你可以通过Jackson自定义反序列化器,或者运行时判断JsonNode类型两种方式实现需求,以下是可直接运行的完整实现:


方案1:自定义反序列化器(推荐,类型处理逻辑内聚)

步骤1:定义外层响应类

给data字段指定自定义反序列化器:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class RootResponse {
    @JsonProperty("value")
    private Value value;

    public static class Value {
        @JsonProperty("data")
        @JsonDeserialize(using = DataDeserializer.class)
        private Object data;
        @JsonProperty("isGraduated")
        private Boolean isGraduated;

        // 可添加工具方法避免业务代码强转
        public boolean isDataStringList() {
            return data instanceof List;
        }

        public boolean isDataInfo() {
            return data instanceof Info;
        }

        // getter、setter省略
    }
    // getter、setter省略
}
步骤2:编写自定义反序列化器

根据JSON节点类型自动匹配反序列化目标类:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.IOException;
import java.util.List;

public class DataDeserializer extends StdDeserializer<Object> {
    protected DataDeserializer() {
        super(Object.class);
    }

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonToken currentToken = p.currentToken();
        // 数组类型直接反序列化为字符串列表
        if (currentToken == JsonToken.START_ARRAY) {
            return p.readValueAs(List.class);
        }
        // 对象类型先取info字段再反序列化为Info类
        if (currentToken == JsonToken.START_OBJECT) {
            DataWrapper wrapper = p.readValueAs(DataWrapper.class);
            return wrapper.getInfo();
        }
        return null;
    }

    // 适配对象2中data的嵌套结构
    private static class DataWrapper {
        @JsonProperty("info")
        private Info info;
        // getter、setter省略
    }
}
步骤3:测试代码
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;

public class DeserializeTest {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        // 测试数组类型的JSON
        String json1 = "{\"value\":{\"data\":[\"John\",\"Justin\",\"Tom\"],\"isGraduated\":false}}";
        RootResponse res1 = objectMapper.readValue(json1, RootResponse.class);
        if (res1.getValue().isDataStringList()) {
            List<String> nameList = (List<String>) res1.getValue().getData();
            System.out.println(nameList); // 输出 [John, Justin, Tom]
        }

        // 测试对象类型的JSON
        String json2 = "{\"value\":{\"data\":{\"info\":{\"background\":{\"primarySchool\":\"A school\",\"univeristy\":\"X univeristy\"},\"name\":\"John\",\"gender\":\"male\",\"dayOfBirth\":\"1995-04-24\"}},\"isGraduated\":false}}";
        RootResponse res2 = objectMapper.readValue(json2, RootResponse.class);
        if (res2.getValue().isDataInfo()) {
            Info info = (Info) res2.getValue().getData();
            System.out.println(info.getName()); // 输出 John
        }
    }
}

方案2:JsonNode运行时转换(无需自定义反序列化器,代码更简洁)

如果不想写反序列化器,可以直接将data字段声明为JsonNode类型,业务代码中手动判断类型转换:

// Value类中data字段定义
@JsonProperty("data")
private JsonNode data;

// 业务代码中转换
ObjectMapper objectMapper = new ObjectMapper();
if (data.isArray()) {
    List<String> nameList = objectMapper.convertValue(data, new TypeReference<List<String>>() {});
} else if (data.isObject()) {
    Info info = objectMapper.convertValue(data.get("info"), Info.class);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:48:02