Я внедряю специальный десериализатор Джексона для одной из моих сущностей.
Моя сущность выглядит следующим образом:
@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);
}
}
Моя проблема в том, что сериализация работает, как и ожидалось - успешно сериализованныйОбъект выглядит следующим образом:
{
"field1Update" : {
"type" : "update",
"value" : "f59c4ef9-52c4-4f3d-99e5-a33a13ae12f3"
},
"field2Update" : {
"type" : "keep"
},
"field3Update" : {
"type" : "reset"
}
}
=> что правильно.(Есть 3 типа обновления, сохранения и сброса).Только для обновления требуется значение.
Проблема заключается в следующем: Когда я десериализую это, только первое поле (field1Update) будет десериализовано.Другие 2 поля (field2Update и field3Update) после завершения десериализации становятся пустыми.
Мой десериализатор выглядит следующим образом:
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);
}
}
}
Интересный факт заключается в том, что Джексон вызывает десериализацию (...)метод только один раз, и я не могу понять, почему ....
Рад, если кто-то может дать мне подсказку.
привет, Майкл