Jackson反序列化时如何将单个属性值映射到两个字段
Jackson实现JSON属性同时赋值给外层类和嵌套对象的解决方案
共有两种常用实现方式,无需对原有JSON结构和测试逻辑做修改:
方案1:使用Jackson反序列化后回调(实现最简,无额外配置)
利用Jackson自带的反序列化生命周期回调能力,在JSON反序列化完成后自动执行属性同步逻辑,不需要自定义反序列化器也不需要修改ObjectMapper配置,仅需调整POJO类即可:
@Data public static class TestData { private String id; private String documentId; private Details details; // 反序列化完成后自动触发执行 @JsonAfterDeserialization private void afterDeserialize() { if (details != null) { details.setDocumentId(this.documentId); } } @Data public static class Details { private String documentId; private String name; private String lastName; } }
调整完成后原有测试用例可直接通过。
方案2:自定义反序列化器实现
如果业务场景不允许修改POJO类的内部逻辑,可以通过自定义反序列化器手动处理属性同步:
- 首先实现自定义反序列化器:
public class TestDataDeserializer extends StdDeserializer<TestData> { public TestDataDeserializer() { super(TestData.class); } @Override public TestData deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode rootNode = p.getCodec().readTree(p); TestData testData = new TestData(); // 赋值外层属性 testData.setId(rootNode.get("id").asText()); String documentId = rootNode.get("documentId").asText(); testData.setDocumentId(documentId); // 反序列化内层嵌套对象 Details details = p.getCodec().treeToValue(rootNode.get("details"), Details.class); // 同步documentId到内层对象 details.setDocumentId(documentId); testData.setDetails(details); return testData; } }
- 注册反序列化器,二选一即可:
- 局部生效:在TestData类上添加注解
@JsonDeserialize(using = TestDataDeserializer.class) - 全局生效:将反序列化器注册到ObjectMapper:
SimpleModule module = new SimpleModule(); module.addDeserializer(TestData.class, new TestDataDeserializer()); objectMapper.registerModule(module);
内容的提问来源于stack exchange,提问作者seenimurugan
相关产品推荐
相关产品推荐

