【问题标题】:Jackson ContextualDeserializer does not deserialize all fieldsJackson ContextualDeserializer 不会反序列化所有字段
【发布时间】:2018-11-17 16:15:13
【问题描述】:

我正在为我的一个实体实现自定义杰克逊反序列化器。

我的实体如下:

@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);
        }
    }
}

一个有趣的事实是,jackson 只调用了一次 deserialize(...) 方法,我不知道为什么....

很高兴有人能给我提示。

你好, 迈克尔

【问题讨论】:

    标签: java jackson deserialization


    【解决方案1】:

    好的 - 经过一段时间的睡眠并分析了 jackson 序列化器中发生的情况,我发现我的反序列化器中没有消耗足够的令牌。

    我的反序列化器的工作版本是:

    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);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2020-01-09
      • 2020-04-30
      • 2021-06-17
      • 2016-02-13
      • 2019-10-21
      • 1970-01-01
      • 1970-01-01
      • 2018-07-31
      • 2016-05-27
      相关资源
      最近更新 更多