编写半自定义反序列化器

问题描述 投票:1回答:1

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

想象一下这些课程:

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字段的默认解串器功能,而无需重写此逻辑。

我怎样才能做到这一点?

spring jackson
1个回答
1
投票

简短的回答

假设您在Article类中有一个默认构造函数,则以下内容应该有效:

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

然后在category中设置article

更长的答案

嗯......我认为你正在偷工减料,超越了定制反序列化器的用途。你可能不想创建这样的耦合。

或者,你可以使用@JsonIdentityInfoObjectIdResolver。你可以从这个answer中描述的方法中获得一些想法。

您可以使用考虑DTO,而不是在您的Web API中公开您的JPA实体。请参阅我之前在answer中描述的原因以供参考。然后你可以有一个映射层将你的实体映射到你的DTO,反之亦然。例如,如果您正在使用MapStruct,那么文档shows an example将介绍如何通过其ID解析实体。

© www.soinside.com 2019 - 2024. All rights reserved.