使用 Gson 通过 Java 17 进行 XMLGregorianCalendar 的 JSON 序列化

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

我正在使用 GSON 使用 JDK 17.0.10 序列化对象。该对象包含 XMLGregorianCalendar 对象,我已注册该对象以进行序列化。应用程序的编译很好,但是当应用程序启动时,这就是我遇到问题的地方,并在为对象调用 GsonBuilder.toJson 时出现以下异常。

com.google.gson.JsonIOException: Failed making field 'com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl#eon' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
    at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
    at com.google.gson.Gson.getAdapter(Gson.java:556)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:55)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
    at com.google.gson.Gson.toJson(Gson.java:842)
    at com.google.gson.Gson.toJson(Gson.java:812)
    at com.google.gson.Gson.toJson(Gson.java:759)
    at com.google.gson.Gson.toJson(Gson.java:736)

我知道当类对象进入 sun API 的内部时,Java 11 提供了警告,与“默认情况下强封装 JDK 内部”(JEP 396) 相关。在 Java 17 中,这些问题会变成错误,API 期望这些问题能够得到解决,因此我在日志中收到了异常。

我尝试在启动时对相关包使用“--add-exports”参数,但没有成功。也许我做错了?但是,我不太喜欢这样做,并且想正确解决问题。

我目前正在使用最新的 Gson (2.10.1),并将其包含在我的代码中。

gsonBuilder.registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarSerializer());

我个人认为,当我确实需要调用“DatatypeFactory.newInstance().newXMLGregorianCalendar”时,GSON API 正在调用“new XMLGregorianCalendar()”,这可能会解决这个问题。我的 XMLGregorianCalendarSerializer 具有对日期内容进行评估的代码,但我将其全部注释掉以返回一个带有空的新 String 对象的新 JsonPrimitive 。我这样做是为了从图片中删除类中的序列化逻辑,以便我可以专注于导致 Java 17 序列化问题的原因。

那么,我错过了什么?有没有办法解决这个问题,或者我是否缺少一些需要添加到代码中来解决此问题的内容?有人有什么想法吗?

仅供参考,去 Jackson JSON 不是我想要走的路。我想修复我的 Gson。

java json gson java-17 xmlgregoriancalendar
1个回答
0
投票

GsonBuilder.registerTypeAdapter
仅为指定类注册适配器,而不为子类注册适配器。但是,
XMLGregorianCalendar
是一个抽象类,从您当前收到的异常中可以看出,您实际上正在序列化 JDK 内部子类
XMLGregorianCalendarImpl

要解决此问题,请使用

GsonBuilder.registerTypeHierarchyAdapter
而不是
registerTypeAdapter

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