java - GSON 未将新字段保存到文件中

标签 java gson

我正在向我的数据类添加新字段,它们没有保存到文件中。没有一个字段是 transient 的。

我正在使用 GSON 加载文件,然后重新保存它以尝试保存新字段。我尝试在构造函数中设置字段并在创建时设置它们。两者都不起作用,我也尝试使用 GSON 以传统方式保存文件,但这也不起作用。修改现有字段可以工作并且可以正确保存,但永远不会创建新字段。

private void loadUserData(Player player) {
    File userFile = new File(userFolder + File.separator + player.getUniqueId().toString() + ".json");

    try {
        if (!userFile.exists()) {
            User user = new User(player.getUniqueId(), player.getName(), player.isOp() ? "§8(§9Manager§8) §9" : "§7", "");

            FileUtils.writeStringToFile(userFile, new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(user), StandardCharsets.UTF_8.name());
            userCache.put(player.getUniqueId(), user);
        } else {
            User user = new GsonBuilder().create().fromJson(new FileReader(userFile), User.class);

            user.save();

            if(!userCache.containsKey(player.getUniqueId())) {
                userCache.put(player.getUniqueId(), user);
            }
        }
    } catch(IOException e) {
        e.printStackTrace();
    }
}
public void save() {
    File userFolder = new File(Core.getInstance().getModuleManager().getModuleInstance(SMPModule.class).getDataFolder() + File.separator + "users");

    try {
        FileUtils.writeStringToFile(new File( userFolder + File.separator + uuid.toString() + ".json"),
                new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(this), StandardCharsets.UTF_8.name());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

数据类:

package net.astreul.core.module.impl.SMP.user;

import com.google.common.collect.Lists;
import com.google.gson.GsonBuilder;
import lombok.AccessLevel;
import lombok.Setter;
import net.astreul.core.Core;
import net.astreul.core.module.impl.SMP.SMPModule;
import net.astreul.core.module.impl.SMP.cosmetic.CosmeticPackage;
import net.astreul.core.util.Format;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

@Setter
public class User {

    @Setter(AccessLevel.NONE) private UUID uuid;
    private String nickname;
    private String prefix;
    private String suffix;
    private long lastLogin;
    private List<CosmeticPackage> ownedCosmetics;
    private List<String> ownedTags;
    private String activeTag;

    public User(UUID uuid, String nickname, String prefix, String suffix) {
        this.uuid = uuid;
        this.nickname = nickname;
        this.prefix = prefix;
        this.suffix = suffix;
        lastLogin = System.currentTimeMillis();
        ownedCosmetics = Lists.newArrayList();
        ownedTags = Lists.newArrayList();
        this.activeTag = "";
    }

    public void save() {
        File userFolder = new File(Core.getInstance().getModuleManager().getModuleInstance(SMPModule.class).getDataFolder() + File.separator + "users");

        try {
            FileUtils.writeStringToFile(new File( userFolder + File.separator + uuid.toString() + ".json"),
                    new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(this));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public File getFile() {
        File userFolder = new File(Core.getInstance().getModuleManager().getModuleInstance(SMPModule.class).getDataFolder() + File.separator + "users");
        return new File( userFolder + File.separator + uuid.toString() + ".json");
    }

    public String getNickname() {
        return Format.color(nickname);
    }

    public String getPrefix() {
        return Format.color(prefix);
    }

    public String getSuffix() {
        return Format.color(suffix);
    }

    public long getLastLogin() {
        return lastLogin;
    }

    public boolean hasPackage(CosmeticPackage cosmeticPackage) {
        return ownedCosmetics.contains(cosmeticPackage);
    }

    public List<CosmeticPackage> getOwnedCosmetics() {
        return ownedCosmetics;
    }

    public List<String> getOwnedTags() {
        return ownedTags;
    }

    public String getActiveTag() {
        return activeTag;
    }
}

我希望它将新字段保存到文件中,但它根本没有保存任何内容。根本没有错误。

最佳答案

我认为这里的问题与gson如何创建实例有关。

如果您查看 gson 的源代码,您会发现它尝试使用以下三种方法之一创建对象实例。首先,它尝试实例创建者——知道如何创建对象的实体。您可以自己注册一个来创建用户 - 检查 here

如果没有,它将检查您没有的默认构造函数。默认构造函数是没有参数的构造函数。

最后一步是尽力创建对象,它使用 Java 的 unsafe 。顾名思义,这样做是不安全的,原因是它绕过了所有构造函数。在您的情况下,它将绕过您在构造函数中放入的任何初始化,并将不在 json 中的字段保留为 null。

如果您不从外部更改字段,一旦保存用户对象,新字段仍然为空,因此不会保存。

要解决此问题,您可以提供实例创建器,或者从其他方法初始化字段,或者以某种方式提供默认构造函数。

关于java - GSON 未将新字段保存到文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57130332/

相关文章:

java - Mac OS X 上的 libGDX 小程序无法加载 libgdx.dylib

java - 接口(interface)列表 - java

java - 对 pow 的调用是模棱两可的

android - com.google.gson.JsonSyntaxException : java. lang.IllegalStateException:应为 BEGIN_ARRAY 但在第 1 行第 3 列路径 $[0] 处为 BEGIN_OBJECT

android - org.json.JSONObject vs Gson 库 JsonObject

java - JSP 中的字符串在 JavaScript 中不起作用

java - Java中使用正则表达式进行匹配?

java - 在使用 GSON 解析 JSON 时使用枚举

java - GSON解析通用Json数组

java - Apache 弗林克 : How do I use a stream of Java Map (or Map containing DTOs)?