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

如何用FastXML JsonProperty将未知键的JSON转为List<PersonInfo>

问题描述

现有如下结构的JSON对象:

{
    "John": { ...Some JSON object... },
    "Mary": { ...Some JSON object... },
    "Sam": { ...Some JSON object... }
}

其中John、Mary、Sam等顶层键对应的JSON值结构完全一致,可映射至Java的PersonInfo类。由于顶层键为未知状态,无法通过如下硬编码@JsonProperty的方式实现映射:

import com.fasterxml.jackson.annotation.JsonProperty;

@Data
public class PersonRecord {
    @JsonProperty("John")
    private PersonInfo john;
}

现需忽略顶层键名称,仅提取所有顶层键对应的值并组成List<PersonInfo>,请问该如何实现?

解决方案

方法1:Map转List(最简洁)

直接将JSON解析为键值对映射,再提取值集合转为List:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;

// 初始化Jackson核心对象
ObjectMapper objectMapper = new ObjectMapper();
// 假设jsonStr是待解析的JSON字符串
Map<String, PersonInfo> personMap = objectMapper.readValue(
    jsonStr,
    new TypeReference<Map<String, PersonInfo>>() {}
);
// 提取所有值转为List
List<PersonInfo> personList = new ArrayList<>(personMap.values());

方法2:自定义反序列化器(适合复杂场景)

如果需要对解析过程做额外处理,比如过滤无效数据,可以自定义反序列化逻辑:

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 java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class PersonListDeserializer extends JsonDeserializer<List<PersonInfo>> {
    @Override
    public List<PersonInfo> deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        JsonNode rootNode = parser.getCodec().readTree(parser);
        List<PersonInfo> personList = new ArrayList<>();
        Iterator<JsonNode> elementIterator = rootNode.elements();
        
        while (elementIterator.hasNext()) {
            JsonNode personNode = elementIterator.next();
            // 将单个节点转为PersonInfo对象
            PersonInfo person = parser.getCodec().treeToValue(personNode, PersonInfo.class);
            personList.add(person);
        }
        return personList;
    }
}

注册并使用该反序列化器:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List;

ObjectMapper objectMapper = new ObjectMapper();
SimpleModule customModule = new SimpleModule();
// 为List<PersonInfo>注册自定义反序列化器
customModule.addDeserializer(
    new TypeReference<List<PersonInfo>>(){}.getType(),
    new PersonListDeserializer()
);
objectMapper.registerModule(customModule);

// 直接解析为List<PersonInfo>
List<PersonInfo> personList = objectMapper.readValue(
    jsonStr,
    new TypeReference<List<PersonInfo>>() {}
);

方法3:遍历JsonNode节点转换

先将JSON解析为JsonNode树结构,再逐个节点转换:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.ArrayList;
import java.util.List;

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonStr);
List<PersonInfo> personList = new ArrayList<>();

// 遍历顶层节点的所有子节点
for (JsonNode node : rootNode) {
    PersonInfo person = objectMapper.convertValue(node, PersonInfo.class);
    personList.add(person);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:03:21