【发布时间】:2022-01-04 17:03:46
【问题描述】:
我正在使用带有 Jackson 的 Spring Boot 应用程序(版本 2.4.5)。我可以添加一个使用 gson 的胖 jar 而不影响应用程序的 Jackson 反序列化吗?
当我将 jar 添加到我的应用程序时,应用程序在任何地方都使用 gson 来反序列化 JSON。但是由于我使用的是 Jackson 的一些特殊功能,所以失败了。
很遗憾,我无法在库中更改它。
我使用 Gradle 在依赖项中添加这样的 fat jar:
implementation fileTree(dir: 'libs', include: ['*.jar'])
我正在构建 Jacksons 对象映射器,例如:
private static ObjectMapper getMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
return mapper;
}
以下行会引发错误:
List<User> users = objectMapper.readValue(getReader("users.json"), new TypeReference<>() {});
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class User (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; onek.books.backend.model.book.Book is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @445d3853)
并且 Gson 被添加到具有以下 maven 依赖项的 fat jar 中:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson-version}</version>
</dependency>
<dependency>
<groupId>io.gsonfire</groupId>
<artifactId>gson-fire</artifactId>
<version>${gson-fire-version}</version>
</dependency>
编辑
正如建议的那样,这不是由于 gson 我试图缩小范围并一一添加所有依赖项,并且没有一个本身导致错误。
但我可能找到了原因,但我不知道如何解决这个问题。这是 Jacksons typeFactory 构造它的类型的方式。对于线路:
List<Book> books = objectMapper.readValue(getReader("books.json"), new TypeReference<>() {});
如果 jar 不存在,则构造的 Type 如下所示:
result = {CollectionType@13667} "[collection type; class java.util.List, contains [simple type, class onek.books.backend.model.book.Book]]"
_elementType = {SimpleType@13669} "[simple type, class onek.books.backend.model.book.Book]"
_superClass = null
_superInterfaces = {JavaType[1]@13670}
_bindings = {TypeBindings@13671} "<Lonek/books/backend/model/book/Book;>"
_canonicalName = null
_class = {Class@352} "interface java.util.List"
_hash = -95724352
_valueHandler = null
_typeHandler = null
_asStatic = false
这是我所期望的,因为 Book-Class 在类型中。但是,如果我添加 jar,则构造的 Type 看起来像:
result = {SimpleType@11757} "[simple type, class java.lang.Object]"
_superClass = null
_superInterfaces = null
_bindings = {TypeBindings@11759} "<>"
_canonicalName = null
_class = {Class@595} "class java.lang.Object"
_hash = 1063877011
_valueHandler = null
_typeHandler = null
_asStatic = false
jackson 将其反序列化为 LinkedHashmap,这种类型会导致 ClassCastException。
但我真的不知道如何从这里继续。外部 jar 可以更改 Jackson TypeFactory 的某些部分吗?
【问题讨论】:
-
根据您提供的代码 sn-p,我不清楚这与 Gson 有什么关系。您明确调用杰克逊的
ObjectMapper中的readValue; Gson 应该对此没有影响。 -
是的,我自己也是这么想的。但很明显,这个带有 gson 的 jar 会导致问题,因为该行没有它但不能使用它。
-
@Marcono1234 你完全正确。依赖没有任何作用(请参阅我的编辑)。但不知何故,jar 改变了类型构造的结果。
标签: java spring-boot jackson gson