gson 将myClass.ChatColor对象与.json文件相互转换会导致出现不需要的前导字符

yqkkidmi  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(164)

我将ChatColor对象存储在一个类对象中。在使用Gson api成功地将它们转换为json之后,我希望能够从这个存储的json文件中示例化内存中的ChatColor对象。
使用下面的代码,我得到了ChatColor对象,它的toString方法返回§6。* 它们应该返回相同的值,但减去前导Â字符 *
为了使这个问题更容易阅读,我已经将示例减少到每个Theme对象一个ChatColor对象。

主题.java

package core.data.objects;

import java.util.Map;
import net.md_5.bungee.api.ChatColor;

public class Theme {

    private ChatColor primary, secondary, tertiary, clear, faded, succeed, fail;

    public Theme(Map<String, ChatColor> thisMap) {
        this.primary = thisMap.get("primary");
    }

    public ChatColor getPrimary() { return primary; }

    public void setPrimary(ChatColor primary) { this.primary = primary; }
}

ThemeManager.java

package core.data;

import core.data.objects.Theme;

import java.io.*;
import java.util.Map;
import java.util.HashMap;

import com.google.gson.Gson;
import net.md_5.bungee.api.ChatColor;

public class ThemeManager {
    public static Theme currentTheme;

    public static void load() throws IOException {
        try {
            currentTheme = getThemeFromJSON(FileManager.defaultThemeFile);

            System.out.println(ChatColor.GOLD);
            System.out.println(currentTheme.getPrimary());

        } catch (Exception e) {
            currentTheme = createDefaultTheme();
            System.out.println("WARN getThemeFromJSON Exception");
            throw new IOException(e.getMessage());
        }
    }

    public static Theme createDefaultTheme() {
        Map<String, ChatColor> thisMap = new HashMap<>();

        thisMap.putIfAbsent("primary", ChatColor.GOLD);
        return new Theme(thisMap);
    }

    public static void writeThemeToJSON(Theme thisTheme, File thisFile) throws IOException {
        Gson gson = new Gson();

        Writer writer = new FileWriter(thisFile, false);
        gson.toJson(thisTheme, writer);
        writer.flush(); writer.close();
    }

    public static Theme getThemeFromJSON(File thisFile) throws FileNotFoundException {
        Gson gson = new Gson();
        Reader reader = new FileReader(thisFile);
        return gson.fromJson(reader, Theme.class);
    }
}

ThemeManager.load()的控制台输出

[20:20:56 INFO]: §6
[20:20:56 INFO]: §6

保存的.json文件示例

{
  "primary": {
    "toString": "§6",
    "name": "gold",
    "ordinal": 6,
    "color": {
      "value": -22016,
      "falpha": 0.0
    }
  }
}

Â不知道从哪里冒出来

68bkxrlz

68bkxrlz1#

解决方案积分:@ dave汤普森085
这个项目(和.json文件)是用UTF-8编码的,但是我没有用UTF-8编码来阅读这个文件,显然这不是FileReader对象的默认编码。
通过更改此项:

public static Theme getThemeFromJSON(File thisFile) throws FileNotFoundException {
    Gson gson = new Gson();
    Reader reader = new FileReader(thisFile);
    return gson.fromJson(reader, Theme.class);
}

更改为:

public static Theme getThemeFromJSON(File thisFile) throws FileNotFoundException {
    Gson gson = new Gson();
    Reader reader = new InputStreamReader (
                new FileInputStream (thisFile), StandardCharsets.UTF_8);
    return gson.fromJson(reader, Theme.class);
}

,ThemeManager.load()中的stdout行现在都显示为预期的§6
但是,请注意,在使用aThemeObject.getPrimary()时,返回的ChatColor对象不能用来代替对ChatColor.COLOR的常规调用。
尝试这样做只会导致“null”出现在游戏中显示的文本中。
为了解决这个问题,我修改了get方法:

public ChatColor getPrimary() {
        return ChatColor.getByChar(primary.toString().charAt(1));
    }

索引1处的char是getByChar方法用于返回clone chatcolor对象的颜色代码。
这将防止在theme.json文件中使用自定义的falpha值和自定义的颜色值,但确保调用Theme.getPrimary()得到的ChatColor对象始终可以用来代替对ChatColor.COLOR的常规调用

相关问题