java - 将多态 Json 对象反序列化为 POJO
问题描述
我将 Json Book 请求定义为
{
"book" : {
"type" : "PRINT",
"value" : {
"weight" : "1lb"
}
}
}
或者
{
"book" : {
"type" : "EBOOK",
"value" : {
"size" : "1MB"
}
}
}
值是一个多态对象。
我将我的 Java POJO 定义如下。我定义value
为多态对象。
@Getter
@Builder
@JsonDeserialize(builder = BookRequest.BookRequestBuilder.class)
public class BookRequest
{
@NonNull
private Book book;
}
书被定义为
@Builder
@Getter
@JsonDeserialize(builder = Book.BookBuilder.class)
public class Book
{
@NonNull
private BookType type;
@NonNull
private BookValue value;
}
BookValue 被定义为一个多态对象。
public interface BookValue
{
}
PrintBook 是一种类型
@Getter
@Builder
@JsonDeserialize(builder = PrintBook.PrintBookBuilder.class)
public class PrintBook implements BookValue
{
private String weight;
}
书籍类型定义为枚举
@Getter
public enum BookType
{
EBOOK,
PRINT
}
当我尝试使用以下代码反序列化 PRINT book json
public deserializePrintBook{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
try {
JsonNode node = createJsonNodeFromFile("src/jacksonannotations/resources/sampleBook.json");
BookRequest br = mapper.treeToValue(node, BookRequest.class);
System.out.println(br);
}
catch (Exception e ) {
e.printStackTrace();
}
}
public static JsonNode createJsonNodeFromFile(final String filePath) throws Exception
{
ObjectMapper objectMapper = new ObjectMapper();
File file = new File(filePath);
JsonNode testMessageEnvelope = objectMapper.readValue(
file,
JsonNode.class);
return testMessageEnvelope;
}
但是,我收到了这个错误
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造实例
jacksonannotations.books.BookValue
(没有创建者,如默认构造函数,存在):抽象类型需要映射到具体类型,具有自定义反序列化器,或者在 [Source : 未知; 行:-1,列:-1](通过参考链:jacksonannotations.books.BookRequest$BookRequestBuilder["book"]->jacksonannotations.books.Book$BookBuilder["value"])
我已经研究了不能构造 - Jackson 的实例,但这没有帮助。
有人可以帮助我理解我是否正确地对上面示例中的 Java pojo 进行建模?
谢谢,帕万
解决方案
从错误消息中,您可以看到 Jackson 尝试构造 BookValue 的实例。这失败了,因为 BookValue 是一个接口。
所以你需要告诉杰克逊应该如何处理这种多态性。此页面提供了一个很好的概述: https ://www.baeldung.com/jackson-inheritance
您没有提供 BookBuilder 实现的详细信息。我假设它遵循常规的构建器模式作为构造器的替代方案。请注意,这并不能帮助 Jackson 确定要实例化哪个子类。
推荐阅读
- javascript - 是否可以使用 onError 重新启动循环?
- python - Python - 从存储在变量中的 SQL 输出中读取特定列
- ruby - 在 macOS Mojave 10.14 上安装 Jekyll
- linux - 无法再安装 Perlapi?
- php - Laravel 组按一种类型的列,并且仅按该类型排序
- android - Android pie - 禁用软件后退按钮会破坏可访问性后退操作
- javascript - 如何在 JQuery 中获取正确的数组长度
- java - java.sql.SQLException:使用 HikariCP [JPA + Hibernate + Guice] 关闭连接
- javascript - 如果另一个数组值等于 x,则获取数组值
- connect - mesos-slave 无法连接没有提供凭据错误