Jackson定制解串器null编解码器

时间:2019-06-10 13:27:01

标签: java jackson deserialization

我为我的类型编写了自定义解串器,表示为interface Attachment,并且该接口PhotoVideo有两种实现。 解析时,我使用鉴别字段从json识别它们。

现在,当jp.getCodec()返回null时,我面临问题,导致 到null pointer exception

为什么这很令人费解以及如何解决?

public class AttachmentDeserializer extends StdDeserializer<Attachment> {

  ObjectMapper objectMapper = new ObjectMapper();

  public AttachmentDeserializer() {
    this(null);
    objectMapper.registerModule(new Jdk8Module());
  }

  public AttachmentDeserializer(Class<Attachment> t) {
    super(t);
    objectMapper.registerModule(new Jdk8Module());
  }

  @Override
  public Attachment deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    JsonNode node = jp.getCodec().readTree(jp);

    String type = node.get("type").asText();

    switch (type) {
      case "photo":
        return new AttachmentPhoto(
            node.get("t").asInt(),
            objectMapper.readValue(node.get("photo").traverse(), Photo.class));

      case "video":
        return new AttachmentVideo(
            node.get("t").asInt(),
            objectMapper.readValue(node.get("video").traverse(), Video.class));

      default:
        throw ctxt.weirdStringException("type", Attachment.class, "Unknown discriminator");
    }
  }
}

附件照片代码:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class AttachmentPhoto implements Attachment {

  private Photo photo;

  public Attachments what() {
    return Attachments.ATTACHMENT_PHOTO;
  }

  public String getDiscriminator() {
    return "photo";
  }

  public AttachmentPhoto() {}

  public AttachmentPhoto(Photo photo) {
    this.photo = photo;
  }

  public Photo getPhoto() {
    return this.photo;
  }

  public AttachmentPhoto setPhoto(Photo v) {
    this.photo = v;
    return this;
  }

  public boolean isAttachmentPhoto() {
    return true;
  }

  public AttachmentPhoto asAttachmentPhoto() {
    return this;
  }

  public boolean isAttachmentVideo() {
    return false;
  }

  public AttachmentVideo asAttachmentVideo() {
    throw new IllegalStateException("Not a $stName: " + this);
  }

  @Override
  public boolean equals(Object thatObj) {
    if (this == thatObj) return true;

    if (!(thatObj instanceof AttachmentPhoto)) return false;

    AttachmentPhoto that = (AttachmentPhoto) thatObj;

    return this.photo.equals(that.photo);
  }

  @Override
  public String toString() {
    return "AttachmentPhoto{" + "photo=" + this.photo + '}';
  }
}

1 个答案:

答案 0 :(得分:0)

您的默认构造函数看起来非常可疑,原因有两个,首先,它使用空类类型调用第二个构造函数,然后将空类型传递给超类,因此使用此构造函数时,覆盖了泛型方法。其次,它没有做任何有用的工作,因为它已经调用了另一个初始化objectMapper的构造函数。您应该删除第一个构造函数,仅保留键入的构造函数,然后使用该构造函数初始化反序列化器。