Jackson ContextualDeserializer不会反序列化所有字段 [英] Jackson ContextualDeserializer does not deserialize all fields
问题描述
我正在为我的一个实体实现自定义jackson反序列化器。
I'm implementing a custom jackson deserializer for one of my entities.
我的实体如下:
@Value
@JsonDeserialize
@AllArgsConstructor
public class TestModel {
private final FieldUpdate<UUID> field1Update;
private final FieldUpdate<UUID> field2Update;
private final FieldUpdate<String> field3Update;
public String toString() {
return "TestModel. Field1="+(field1Update != null ? field1Update.toString() : null)+
" Field2="+(field2Update != null ? field2Update.getClass().getName() : null) +
" Field3="+(field3Update != null ? field3Update.getClass().getName() : null);
}
}
我的问题是序列按预期工作 - 成功序列化对象如下:
My problem is that serialiation works as expected - the successfully serialized object is as follow:
{
"field1Update" : {
"type" : "update",
"value" : "f59c4ef9-52c4-4f3d-99e5-a33a13ae12f3"
},
"field2Update" : {
"type" : "keep"
},
"field3Update" : {
"type" : "reset"
}
}
=>这是正确的。
(有3种类型更新,保留和重置)。只有更新需要一个值。
=> which is correct. (There are the 3 Types Update, Keep and Reset). Only update needs a value.
问题是:当我反序列化时,只有第一个字段(field1Update)被反序列化。反序列化完成后,其他2个字段(field2Update和field3Update)为空。
The problem is: When i deserialize this, only the first field (field1Update) gets deserialized. The other 2 fields (field2Update and field3Update) are null after deserialization completes.
我的反序列化器如下:
public class FieldUpdateDeserializer extends StdDeserializer implements ContextualDeserializer {
private JavaType contentType;
public FieldUpdateDeserializer(JavaType contentType) {
this(null,contentType);
}
public FieldUpdateDeserializer() {
this(null,null);
}
public FieldUpdateDeserializer(Class<?> vc, JavaType contentType) {
super(vc);
this.contentType = contentType;
}
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException {
JavaType t = property.getType();
JavaType boundType = t.getBindings().getBoundType(0);
return new FieldUpdateDeserializer(boundType);
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctx) throws IOException {
if(!"type".equals(jp.nextFieldName()) )throw new JsonParseException(jp,"'type' expected");
String typeVal = jp.nextTextValue();
if("update".equals(typeVal)) {
jp.nextValue(); //consume type.
try {
JsonDeserializer deser = ctx.findNonContextualValueDeserializer(contentType);
return new Update<>(deser.deserialize(jp,ctx));
} catch (Exception ex) {
throw new IllegalStateException("Could not handle deserialization for type", ex);
}
} else if("keep".equals(typeVal)) {
return new Keep<>();
} else if("reset".equals(typeVal)) {
return new Reset<>();
} else {
return ctx.handleUnexpectedToken(FieldUpdate.class, jp);
}
}
}
一个有趣的事实是杰克逊只调用deserialize(...)方法一次,我无法弄清楚为什么....
An interesting fact is that jackson calls the deserialize(...) method only one time and i can't figure out why....
如果有人能给我一个提示,我很高兴。
Glad if somebody can drop me a hint.
问候,
Michael
greetings, Michael
推荐答案
好的 - 经过一段时间的睡眠并分析杰克森序列化器中发生的事情,我发现我的反序列化器中没有消耗足够的令牌。
Ok - after some sleep and analyzing what happens in the jackson serializer, i discovered that i did not consume enough tokens in my deserializer.
我的解串器的工作版本是:
The working version for my deserializer is:
public Object deserialize(JsonParser jp, DeserializationContext ctx) throws IOException {
if(!"type".equals(jp.nextFieldName()) )throw new JsonParseException(jp,"'type' expected");
String typeVal = jp.nextTextValue();
if("update".equals(typeVal)) {
jp.nextValue(); //consume type.
try {
JsonDeserializer deser = ctx.findNonContextualValueDeserializer(contentType);
return new Update<>(deser.deserialize(jp,ctx));
} catch (Exception ex) {
throw new IllegalStateException("Could not handle deserialization for type", ex);
} finally {
jp.nextToken();
}
} else if("keep".equals(typeVal)) {
jp.nextToken();
return new Keep<>();
} else if("reset".equals(typeVal)) {
jp.nextToken();
return new Reset<>();
} else {
return ctx.handleUnexpectedToken(FieldUpdate.class, jp);
}
}
这篇关于Jackson ContextualDeserializer不会反序列化所有字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!