使用 Jackson 自定义反序列化:扩展默认反序列化器
Posted
技术标签:
【中文标题】使用 Jackson 自定义反序列化:扩展默认反序列化器【英文标题】:Custom deserialization with Jackson: extend default deserializer 【发布时间】:2018-07-15 03:00:54 【问题描述】:我想通过扩展默认值并在其后设置更多值来制作自己的反序列化器:
simplified code:
public class Dto
public String originalJsonString;
public MyFooDto extends Dto
public String myField;
@Bean
public ObjectMapper deserializingObjectMapper()
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(MyFooDto.class, new JsonDtoDeserializer<>());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
// or maybe instead of the Beam just @JsonDeserialize(using = JsonDtoDeserializer.class) before MyFooDto?
public class JsonDtoDeserializer<T extends Dto> extends StdDeserializer<T>
// or maybe extends JsonDeserializer? or UntypedObjectDeserializer? or UntypedObjectDeserializer.Vanilla?
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
// here I would like:
T item = super.deserialize"AsUsual"(p, ctxt);
// the difficulty is to avoid the loop of death, where the deserializer would call itself for the eternity...
// And then set other Dto-fields depending on the original Json input, for example:
item.originalJsonString = p.readValueAsTree().toString();
return item;
如你所见,我也想为其他 DTO 重用这个 Dto 母类。
我没有找到任何例子。我真的是世界第一吗? 反序列化“AsUsual”(p, ctxt) 应该是什么? 我应该使用什么motherclass? JsonDeserializer / StdDeserializer / UntypedObjectDeserializer? 反序列化器会知道它必须实例化哪个类的 T 吗?感谢社区!
【问题讨论】:
mother class
的正确术语是 super class
关于反序列化“AsUsual”见***.com/questions/18313323/…
How do I call the default deserializer from a custom deserializer in Jackson的可能重复
【参考方案1】:
正如莎伦所说(基于How do I call the default deserializer from a custom deserializer in Jackson)
@Bean
public ObjectMapper serializingObjectMapper()
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.setDeserializerModifier(new BeanDeserializerModifier()
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
if (Dto.class.isAssignableFrom(beanDesc.getBeanClass()))
return new JsonDtoDeserializer<>(deserializer, beanDesc.getBeanClass());
return deserializer;
);
objectMapper.registerModule(simpleModule);
return objectMapper;
public class JsonDtoDeserializer<T extends Dto> extends StdDeserializer<T> implements ResolvableDeserializer /*StdDeserializer<Dto<T>>*/ /*UntypedObjectDeserializer.Vanilla*/ /*<T>*/ /*implements ResolvableDeserializer*/
private final JsonDeserializer<?> defaultDeserializer;
public JsonDtoDeserializer(JsonDeserializer<?> defaultDeserializer, Class<?> clazz)
super(clazz);
this.defaultDeserializer = defaultDeserializer;
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
@SuppressWarnings("unchecked")
T itemObj = (T) defaultDeserializer.deserialize(p, ctxt);
return itemObj;
// for some reason you have to implement ResolvableDeserializer when modifying BeanDeserializer
// otherwise deserializing throws JsonMappingException??
@Override public void resolve(DeserializationContext ctxt) throws JsonMappingException
((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
【讨论】:
以上是关于使用 Jackson 自定义反序列化:扩展默认反序列化器的主要内容,如果未能解决你的问题,请参考以下文章
Jackson 使用自定义日期格式错误地反序列化 Joda 日期
Spring Boot 1.4 自定义内部 Jackson 反序列化
当值为“null”时,Jackson 忽略自定义字段反序列化器