如何通过Jackson注解将personId作为Map键解析为Map<String,Person>结构
结论
可以通过Jackson相关注解实现该需求,以下是两种常用实现方案:
方案1:自定义反序列化器 + 注解指定(纯注解实现)
不需要额外的业务转换逻辑,直接通过Jackson注解指定反序列化规则即可:
- 保持现有
Person类不变:
public class Person { private String name; private int age; // getter/setter 省略 }
- 编写针对
Map<String, Person>的自定义反序列化器:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class PersonMapDeserializer extends StdDeserializer<Map<String, Person>> { public PersonMapDeserializer() { super(Map.class); } @Override public Map<String, Person> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { Map<String, Person> resultMap = new HashMap<>(); // 解析外层JSON数组 JsonNode arrayNode = p.getCodec().readTree(p); for (JsonNode node : arrayNode) { String personId = node.get("personId").asText(); Person person = p.getCodec().treeToValue(node.get("infoPerson"), Person.class); resultMap.put(personId, person); } return resultMap; } }
- 在你的Map属性上添加
@JsonDeserialize注解指定反序列化器即可:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.Map; public class YourBusinessClass { @JsonDeserialize(using = PersonMapDeserializer.class) private Map<String,Person> pMap; // getter/setter 省略 }
方案2:DTO中转实现(逻辑更直观,无自定义序列化器)
如果不想写自定义反序列化逻辑,可以通过临时DTO接收后转换,代码可读性更高:
- 定义单条数据的接收DTO:
public class PersonEntry { private String personId; private Person infoPerson; // getter/setter 省略 }
- 反序列化时先转成列表再批量转换为Map:
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 反序列化逻辑示例 ObjectMapper objectMapper = new ObjectMapper(); List<PersonEntry> entryList = objectMapper.readValue(你的JSON字符串, new TypeReference<List<PersonEntry>>() {}); Map<String, Person> pMap = entryList.stream() .collect(Collectors.toMap(PersonEntry::getPersonId, PersonEntry::getInfoPerson));
注意:如果你的JSON最外层不是数组而是单个对象,仅需要调整自定义反序列化器的解析逻辑,去掉数组遍历步骤即可。
内容的提问来源于stack exchange,提问作者Alvins
相关产品推荐
相关产品推荐

