【问题标题】:Converting myClass.ChatColor objects to and from .json files result in undesired leading `Â` characters将 myClass.ChatColor 对象与 .json 文件相互转换会导致不需要的前导 `Â` 字符
【发布时间】:2021-06-03 02:45:24
【问题描述】:

我将 ChatColor 对象存储在类对象中。使用 Gson api 成功将它们转换为 json 后,我希望能够从这个存储的 json 文件中实例化内存中的 ChatColor 对象。

使用下面的代码,我得到了 toString 方法返回 §6 的 ChatColor 对象。 它们应该返回相同但减去前导  字符

为了使这个问题更易于阅读,我将示例缩减为每个 Theme 对象一个 ChatColor 对象。

Theme.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
    }
  }
}

 不知从何而来!

【问题讨论】:

  • 这个问题很可能是由于错误的字符集,用正确的字符集构建你的 FileReader,它应该可以缓解问题。
  • @AnthonyCathers 怎么做?在 JavaDocs 中,FileReady 在构造函数中似乎没有 charset 参数?
  • Since 11 FileReader does have ctors taking charset;在此之前或以其他方式使用new InputStreamReader (new FileInputStream (file), charset)。或者在启动时使用-Dfile.encoding= 设置JVM 默认值。在应该是 A0 或 80 到 FF 的字符之前有一个额外的 cap-A-hat (C2) 是使用 UTF-8 的特征,其中 8859(例如 Latin-1)或类似的类似 WIndows-1252。
  • @dave_thompson_085 您的解决方案有效!随意添加答案,以便我接受它,您可以获得学分:)(使用您评论中的 InputStreamReader 方法)

标签: java json gson minecraft bukkit


【解决方案1】:

解决方案来源:@dave_thompson_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() 的标准输出行现在都按预期显示 §6

但是,请注意,在使用 aThemeObject.getPrimary() 时,返回的 ChatColor 对象无法用于代替对 ChatColor.COLOR 的常规调用。

尝试这样做只会导致“null”出现在游戏中显示的文本中。

为了解决这个问题,我将 get 方法修改为:

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

索引 1 处的字符是 getByChar 方法用于返回克隆 chatcolor 对象的颜色代码。

这将阻止在 theme.json 文件中使用自定义 falpha 值和自定义颜色值,但确保始终可以使用调用 Theme.getPrimary() 生成的 ChatColor 对象来代替对 ChatColor.COLOR 的常规调用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    相关资源
    最近更新 更多