如何在Jackson自定义复杂反序列化器中复用已有类映射?
仅对Jackson反序列化中特定子类手动处理的实现方案
完全可行,有两种简洁的实现方式,无需手动映射所有子类:
方案一:针对TestClass自定义反序列化器,复用默认逻辑处理大部分字段
先让Jackson自动完成TestClass及大部分子类的反序列化,仅替换Class10的实例为手动处理的结果:
public class TestClassDeserializer extends StdDeserializer<TestClass> { private final ObjectMapper defaultMapper; public TestClassDeserializer() { super(TestClass.class); this.defaultMapper = new ObjectMapper(); } @Override public TestClass deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // 1. 用默认逻辑自动反序列化整个TestClass TestClass testClass = defaultMapper.readValue(jp, TestClass.class); // 2. 重置解析器,重新读取JSON节点以处理Class10 jp.reset(); JsonNode rootNode = jp.getCodec().readTree(jp); JsonNode class10Node = rootNode.get("ten"); // 3. 手动实例化并配置Class10 Class10 customClass10 = new Class10(); customClass10.setField1(class10Node.get("field1").asText()); // 补充其他需要手动处理的字段 // 4. 替换自动生成的Class10实例 testClass.setTen(customClass10); return testClass; } }
注册反序列化器后即可使用:
ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(TestClass.class, new TestClassDeserializer()); mapper.registerModule(module); TestClass result = mapper.readValue(jsonString, TestClass.class);
方案二:单独给Class10注册自定义反序列化器(推荐)
直接针对Class10编写反序列化逻辑,Jackson处理TestClass时,会自动用默认逻辑解析其他字段,遇到Class10类型的ten字段时,自动调用其自定义反序列化器:
public class Class10Deserializer extends StdDeserializer<Class10> { public Class10Deserializer() { super(Class10.class); } @Override public Class10 deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode node = jp.getCodec().readTree(jp); Class10 class10 = new Class10(); class10.setField1(node.get("field1").asText()); // 编写Class10的手动处理逻辑 return class10; } }
注册后直接反序列化TestClass即可:
ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(Class10.class, new Class10Deserializer()); mapper.registerModule(module); TestClass result = mapper.readValue(jsonString, TestClass.class);
这种方式更简洁,无需修改TestClass的反序列化逻辑,仅对目标类做定制,是更推荐的实现方式。
内容的提问来源于stack exchange,提问作者Arzybek
相关产品推荐
相关产品推荐

