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

Java——如何正确配置和使用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吗?

共有1个答案

谷梁晟
2023-03-14

您的POJO只需实现可序列化接口,然后您就可以轻松地在带有文件流的文件中写入和读取该类。你可以在这里找到更多信息

 类似资料:
  • 我正在用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。 我很难使用枚举。

  • 我在我的多线程应用程序中使用了Java Executors,但我似乎不知道什么时候使用以下每一种方式是最好的: 我想知道的是:这些方法是可以互换的,还是在某种情况下我应该使用上面的特定类型?

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