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

如何用Jackson/ObjectMapper将特定JSON反序列化为Java对象?

使用Jackson实现动态Key的JSON反序列化

核心思路

你的需求本质是要把JSON中以key/value形式存储的属性,映射到Java类的对应字段上,同时区分不同的对象类型(Account/User)。解决方案是自定义Jackson反序列化器,通过解析attribute数组构建键值对,再根据键判断目标对象类型,最终完成映射。

步骤1:调整并完善Java类定义

给Response的items字段添加反序列化注解,指定自定义的反序列化器;保留你原有的Header、Account、User类:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.List;

public class Response {
    private Header header;
    // 指定自定义反序列化器处理items字段
    @JsonDeserialize(using = ItemListDeserializer.class)
    private List<Object> items;

    // getters and setters
}

public class Header {
    private String transactionId;
    private String application;

    // getters and setters
}

public class Account {
    private String accountType;
    private String accountId;

    // getters and setters
}

public class User {
    private String userType;
    private String userId;

    // getters and setters
}

步骤2:编写自定义反序列化器

创建ItemListDeserializer类,继承JsonDeserializer<List<Object>>,实现自定义解析逻辑:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ItemListDeserializer extends JsonDeserializer<List<Object>> {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public List<Object> deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        List<Object> resultList = new ArrayList<>();
        JsonNode rootNode = parser.getCodec().readTree(parser);
        // 读取items下的item数组
        JsonNode itemArrayNode = rootNode.get("item");

        for (JsonNode itemNode : itemArrayNode) {
            // 解析当前item的attribute数组,转为键值对Map
            JsonNode attributeArrayNode = itemNode.get("attributes").get("attribute");
            Map<String, String> attrMap = new HashMap<>();
            for (JsonNode attrNode : attributeArrayNode) {
                String key = attrNode.get("key").asText();
                String value = attrNode.get("value").asText();
                attrMap.put(key, value);
            }

            // 根据Map中的key判断目标对象类型
            Object targetObj;
            if (attrMap.containsKey("accountType")) {
                targetObj = objectMapper.convertValue(attrMap, Account.class);
            } else if (attrMap.containsKey("userType")) {
                targetObj = objectMapper.convertValue(attrMap, User.class);
            } else {
                // 处理未知类型,可根据需求调整
                targetObj = attrMap;
            }
            resultList.add(targetObj);
        }
        return resultList;
    }
}

步骤3:执行反序列化测试

使用ObjectMapper完成反序列化操作:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class DeserializeTest {
    public static void main(String[] args) throws IOException {
        String jsonStr = "{\n" +
                "  \"header\": {\n" +
                "    \"transactionId\": \"12345\",\n" +
                "    \"application\": \"testApp\"\n" +
                "  },\n" +
                "  \"items\": {\n" +
                "    \"item\": [\n" +
                "      {\n" +
                "        \"attributes\": {\n" +
                "          \"attribute\": [\n" +
                "            {\n" +
                "              \"key\": \"accountType\",\n" +
                "              \"value\": \"TYPE1\"\n" +
                "            },\n" +
                "            {\n" +
                "              \"key\": \"accountId\",\n" +
                "              \"value\": \"123\"\n" +
                "            }\n" +
                "          ]\n" +
                "        }\n" +
                "      },\n" +
                "      {\n" +
                "        \"attributes\": {\n" +
                "          \"attribute\": [\n" +
                "            {\n" +
                "              \"key\": \"userType\",\n" +
                "              \"value\": \"TYPE2\"\n" +
                "            },\n" +
                "            {\n" +
                "              \"key\": \"userId\",\n" +
                "              \"value\": \"321\"\n" +
                "            }\n" +
                "          ]\n" +
                "        }\n" +
                "      }\n" +
                "    ]\n" +
                "  }\n" +
                "}";

        ObjectMapper mapper = new ObjectMapper();
        Response response = mapper.readValue(jsonStr, Response.class);

        // 验证结果
        System.out.println("Header TransactionId: " + response.getHeader().getTransactionId());
        for (Object item : response.getItems()) {
            if (item instanceof Account) {
                Account account = (Account) item;
                System.out.println("Account Type: " + account.getAccountType() + ", ID: " + account.getAccountId());
            } else if (item instanceof User) {
                User user = (User) item;
                System.out.println("User Type: " + user.getUserType() + ", ID: " + user.getUserId());
            }
        }
    }
}

关键说明

  • 自定义反序列化器负责解析JSON中嵌套的attribute结构,将key/value转为Map,再通过Jackson的convertValue方法自动映射到目标Java类。
  • 通过判断Map中的特征key(如accountType、userType)来区分要实例化的对象类型,可根据实际需求扩展更多类型判断逻辑。
  • 确保所有Java类都有完整的getter/setter方法,Jackson需要通过这些方法完成字段赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:20:19