编写一个半定制的反序列化器

时间:2019-04-16 11:47:53

标签: spring jackson

我想编写一个自定义反序列化组件,该组件仍将使用某些默认功能:

想象一下这些类:

class Category {
    private Long id;
    private String name;
}

class Article {
    private Long id;
    private String title;
    private Category category;
}

这个JSON有效负载:

{
  "id": 1,
  "title": "Pray for Notre Dame",
  "category_id": 5
}

根据对在线阅读的各种文章的理解,我应该编写一个自定义反序列化器来处理我的category_id字段:

@JsonComponent
public class ArticleJsonDeserializer extends JsonDeserializer<Article> {

    @Override
    public Article deserialize(JsonParser jsonParser, 
      DeserializationContext deserializationContext) throws IOException, 
      JsonProcessingException {

        TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
        TextNode category = this.entityManager.getReference(Category.class, treeNode.get("category_id"));

        // The following lines bother me
        String title = treeNode.get("title");
        Long id = treeNode.get("id");

        return new Article(id, title, category);
    }
}

但是,实际上,我很想在titleid字段中使用默认的反序列化器功能,而无需重写此逻辑。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

简短答案

假设您在Article类中具有默认的构造函数,则应该可以进行以下操作:

Article article = jsonParser.getCodec().treeToValue(treeNode, Article.class);

然后在category中设置article

答案更长一点

嗯...我想您正在偷工减料,超越了自定义解串器的用途。您可能不想创建这样的耦合。

或者,您可以将@JsonIdentityInfoObjectIdResolver一起使用。您可以从此answer中描述的方法中获得一些想法。

您可以使用考虑的DTO来代替在Web API中公开JPA实体。请参阅我在先前的answer中描述的原因以供参考。然后,您可以具有一个映射层将实体映射到DTO,反之亦然。例如,如果您使用的是MapStruct,则有关如何通过实体ID解析实体的文档shows an example