Пользовательский десериализатор Джексона с нулевым кодеком - PullRequest
0 голосов
/ 10 июня 2019

Я написал собственный десериализатор для моего типа, который представлен как interface Attachment, и есть два варианта реализации этого интерфейса Photo и Video. При разборе я узнаю их по 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 голосов
/ 10 июня 2019

Ваш конструктор по умолчанию выглядит очень подозрительно по двум причинам: сначала он вызывает второй конструктор с нулевым типом класса, который затем передает нулевой тип суперклассу, следовательно, переопределенный универсальный метод портится при использовании этого конструктора.Во-вторых, это бесполезная работа, так как он уже вызывает другой конструктор, который инициализирует objectMapper.Вы должны удалить первый конструктор, оставить только типизированный и инициализировать десериализатор, используя его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...