我想编写一个仍然使用一些默认功能的自定义反序列化组件:
想象一下这些课程:
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);
}
}
但是,实际上,我很乐意使用title
和id
字段的默认解串器功能,而无需重写此逻辑。
我怎样才能做到这一点?
假设您在Article
类中有一个默认构造函数,则以下内容应该有效:
Article article = jsonParser.getCodec().treeToValue(treeNode, Article.class);
然后在category
中设置article
。
嗯......我认为你正在偷工减料,超越了定制反序列化器的用途。你可能不想创建这样的耦合。
或者,你可以使用@JsonIdentityInfo
和ObjectIdResolver
。你可以从这个answer中描述的方法中获得一些想法。
您可以使用考虑DTO,而不是在您的Web API中公开您的JPA实体。请参阅我之前在answer中描述的原因以供参考。然后你可以有一个映射层将你的实体映射到你的DTO,反之亦然。例如,如果您正在使用MapStruct,那么文档shows an example将介绍如何通过其ID解析实体。