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

如何正确配置和使用Gson?

易俊远
2023-03-14

我正在用Java Swing制作一个游戏,其中有一个大POJO用来存储游戏的运行时数据,比如精灵的位置、当前显示的效果等等。我希望能够将其作为JSON保存到一个文件中,然后在以后重新构建。我发现Gson应该就是这么做的,但到目前为止我还没能让它工作。我总是遇到这样一个问题:它无法使嵌套在存储类中的某些变量可访问。

以下是我目前使用Gson的方式:

public void loadGameState(String path) throws FileNotFoundException {
    gameStateData = gson.fromJson(new FileReader(path), gameStateData.getClass());
}

public void writeGameState(String path) throws IOException {
    gson.toJson(gameStateData, new FileWriter(path));
}

以下是我当前尝试使用writeGameState时收到的错误消息

Exception in thread "AWT-EventQueue-0" com.google.gson.JsonIOException: Failed making field 'java.util.Random#seed' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
    at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:22)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:158)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
    at com.google.gson.Gson.getAdapter(Gson.java:501)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:116)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:165)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
    at com.google.gson.Gson.getAdapter(Gson.java:501)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:116)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:165)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
    at com.google.gson.Gson.getAdapter(Gson.java:501)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:53)
    at com.google.gson.Gson.getAdapter(Gson.java:501)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:116)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:165)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
    at com.google.gson.Gson.getAdapter(Gson.java:501)
    at com.google.gson.Gson.toJson(Gson.java:739)
    at com.google.gson.Gson.toJson(Gson.java:726)
    at com.google.gson.Gson.toJson(Gson.java:701)
    at gamestatedata.GameStateManager.writeGameState(GameStateManager.java:27)
    at rendering.MainWindow.actionPerformed(MainWindow.java:205)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.concurrent.atomic.AtomicLong java.util.Random.seed accessible: module java.base does not "opens java.util" to unnamed module @55129b54
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
    at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:19)
    ... 57 more

GameStateData是我在开头提到的大POJO,它大约有300行,包含30个变量和它们的getter,所以我不确定粘贴它是否有帮助。我的POJO中的所有字段都是私有的,但我尝试将它们全部设置为受保护的或所有为公共的,但这没有帮助,因为有些字段还包含私有或受保护的字段,因此仍然会出现相同的问题。

我正在使用java 17.0.0和Gson 2.9.0以及Maven。我想我是在使用Maven来导入Gson,但我真的有点困惑它是如何工作的,但这是我的pom。xml只是为了确保:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>hu.elte.inf</groupId>
    <artifactId>ThesisMVN</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
</project>

据我所知,这可以通过将Gson移动到类路径来解决,但我已经这样做了,但仍然遇到了这个问题。是否有一个关于如何确保它正常工作的分步指南?还有其他工具可以让我轻松地从Java对象读写JSON吗?

这个问题存在于我的POJO中,我掩盖了我收到的错误消息,以及我对序列化和transient关键字缺乏了解。我的POJO有几张图片,无论如何都应该是暂时的,我的问题的另一个来源是一个无法正常访问的随机实例。TLDR:使用transient关键字并注意错误消息。

共有1个答案

沈单弓
2023-03-14

您的POJO可以实现Serializable接口,然后您可以轻松地在文件流中/从文件中写入和读取该类

 类似资料:
  • 我正在用Java Swing制作一个游戏,其中有一个大POJO用来存储游戏的运行时数据,比如精灵的位置、当前显示的效果等等。我希望能够将其作为Json保存到一个文件中,然后在以后重新构建。我发现Gson应该就是这么做的,但到目前为止我还没能让它工作。我总是遇到这样一个问题:它无法使嵌套在存储类中的某些变量可访问 以下是我目前使用Gson的方式: 这是当我尝试使用时,我当前收到的错误消息: 是我一开

  • 我试图完成本教程,但我认为在配置网页时遇到了一些问题。我正在一步一步地制作教程,但它不起作用。。 错误]无法执行目标com。github。eirslett:frontend maven插件:1.10.3:project shop上的webpack(webpack生成):无法运行任务:“webpack”。js'失败了。组织。阿帕奇。平民执行官。ExecuteException:进程已退出,但出现错误

  • 我正在尝试创建一个CXF肥皂Web服务客户端,以便使用经过Kerberos身份验证的SharePoint实例进行肥皂调用。 我导入以下内容: 组织。阿帕奇。cxf:cxf rt前端jaxws:3.2.6 组织。阿帕奇。cxf:cxf rt传输http:3.2.6 组织。阿帕奇。cxf:cxf rt传输http hc:3.2.6 组织。阿帕奇。cxf:cxf rt ws-security:3.2.6

  • 我正在Java Spring/Hibernate中使用Swagger-UI。Swagger UI版本是2。 我很难使用枚举。

  • 我有一个身份提供程序,我希望针对使用SAML 2.0预形成SSO 我正在使用https://github.com/KentorIT/authservices IdP配置是: Entity Id:https://xxx.yyy.com/auth 断言消费者服务URL:超文本传输协议://zzz: 1111/AuthServices/Acs 我创建了一个自签名证书并将其添加到本地项目中。 本地配置:

  • 为了获得python方面的培训,我决定使用脚本绘制mandelbrot集。绘制它并不太复杂,所以我决定使用颜色,我发现了平滑着色算法。使用这个问题,我能够渲染出一些非常漂亮的东西,类似于这个。 为了实现这一点,我使用三个“步骤”设置了渐变调色板:从深蓝色到浅蓝色,然后从浅蓝色到黄色,最后从黄色到深棕色。整体形象完美。 当我试图太放大时,问题就来了。让我们以这个区域为例。当我处于这种缩放水平时,我的