如何用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
相关产品推荐
相关产品推荐

