当前位置: 首页 > 知识库问答 >
问题:

使用Jackson的Spring Boot和带有Gson的外部库

卫华奥
2023-03-14

我在Jackson上使用Spring Boot应用程序(2.4.5版)。我可以添加一个使用gson的胖罐子,而不影响应用程序的Jackson反序列化吗?

当我将jar添加到我的应用程序时,应用程序到处使用gson来反序列化JSON。但是因为我使用了杰克逊的一些特殊功能,所以失败了。

不幸的是,我不能在图书馆里改变这一点。

我使用Gradle在依赖项中添加胖罐子,如下所示:

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被添加到fat jar中,具有以下maven依赖项:

<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不存在,则构造的类型如下所示:

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类是。但如果我添加jar,构造的类型如下所示:

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,这种类型会导致ClassCastExcture。

但是我真的不知道如何从这里继续下去。一个外部罐子能改变杰克逊打字厂的一些部分吗?

共有2个答案

楮杰
2023-03-14

最有可能的问题在于创建“胖JAR”。

创建胖JAR时,请注意以下事项:

  • 依赖项提供的META-INF/MANIFEST. MF应被忽略
  • module-info.class和META-INF版本/

如果您使用插件生成胖罐子,那么它可能会为这些转换提供设置(或者默认情况下执行这些设置)。

何升
2023-03-14

当Jackson尝试反序列化一个没有提供类型信息的对象时,它使用一个LinkedHashMap来存储对象属性值。异常可能与此相关。

我的猜测是,这个胖罐子可能包含了一个不同版本的Jackson,与你在项目中包含的版本不同,出于某种原因,这种行为是不同的。

我不知道这是否只是一个不准确的问题,但为了解决这个问题,尝试提供实际类型在您的类型参考

List<Book> books = objectMapper.readValue(getReader("books.json"), new TypeReference<List<Book>>() {});

请考虑阅读相关文章和问题。

 类似资料:
  • 我正在尝试建立一个带有外部文件链接的PDF文件。 我使用的规范是https://www.adobe.com/content/dam/adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf 在第348页上有一个具有远程加载的替代图像的图像示例。当我使用文档中的示例创建文档时,阅读器(使用acrobat reader XI)不会获取图像。没有错误消息,但没

  • 我们曾经有一个包含EJB jar和WAR的EAR。我们从EJB向战争发送了一个dto类。一切都很好。 现在我们已经尝试从EAR中提取WAR,并创建了WAR使用的EJB-client(API jar)。这个API jar包括我们从EJB发送到WAR的dto类。在EAR中,API部署在lib目录中。 在WAR中,我们在WEB-INF/lib目录中有相同的API jar。 但现在我们在访问dto类的内部

  • 我一直在尝试将jar转换为exe。该程序(jar)使用蓝牙库“Bluecove”,这是某个目录中的另一个jar。该程序还使用Java Swing,通常是JFrame等。当从Netbeans或Eclipse中运行时,该程序运行良好。现在是我部署它的时候了,因此我需要将其转换为exe。但我一直无法让最终的可执行文件与“Bluecove”链接。我尝试了JSmooth和Launch4j,但是使用这两个工具

  • 问题内容: 我已经在一个docker容器中运行了一个gitlab服务器,并在另一个docker容器中运行了一个外部nginx服务器,因此gitlab nginx服务器被停用了。现在我想使用gitlab服务器中包含的docker注册表。 我尝试从管理手册中获取信息:https : //docs.gitlab.com/ee/administration/container_registry.html

  • 我对Hibernate Spring MVC有几个问题。这是我从控制器调用数据库实体的示例: 控制器 服务 数据库服务 带有命名查询的car服务 汽车储存库 汽车实体 @Table(name = "car ",catalog = "ATS ")公共类car实现java.io.Serializable { 车型(外键链接,一对多关系) 车队实体 收购实体 我正在使用maven和4.2.1.RELEA

  • 让我预先感谢你的帮助! 我在一个spring boot应用程序中有一个奇怪的行为。我来给你解释一下: 我正在用一些不错的rest-json服务包装一些遗留的Web服务(自定义xml消息)(通过spring-mvc和Spring boots并使用jackson序列化东西) 为了与遗留系统通信,我创建了一个自定义XmlMapper、序列化器和反序列化器。 最后,我创建了一个httpclientconf