JSON jackson 读取 Class hashmap 的值作为 LinkedHashMap

JSON jackson reading Class values of hashmaps as LinkedHashMap

我将一个分数 (KillcountRatio class) 保存到一个 HashMap 中的名称 (String),我用 Jackson JSON 保存了它,但是在加载保存的 json 时文件,它无法将存储在具有特定键的 HashMap 中的 KillCountRatio class 值转换为 KillCountRatio,它给出

java.util.LinkedHashMap 无法转换为 KillCountRatio

因为存储在 HashMap 中的值不再是 KillCountRatio,而是 LinkedHashMap。

不确定要尝试什么。

这是 KillCountRatio class:

public final class KillCountRatio {

    private int killCount;

    private int deathCount;

}

这是 HashMap,其中存储了上面的内容并给定了一个字符串键,然后用 Jackson JSON 保存。

private HashMap<String, KillCountRatio> savedScores = new HashMap<>();

保存和加载:

public void save() {
    ObjectWriter  writer = new ObjectMapper().writer().withDefaultPrettyPrinter();
    File f = new File("data/savedScores.json");
    try {
        writer.writeValue(f, savedScores); //written here
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void load() {

    savedScores = new ObjectMapper().readValue(new File("data/savedScores.json"), new HashMap<String, KillCountRatio>().getClass());
}

这是错误:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.datarepo.KillCountRatio

我该怎么做才能克服这个转换错误?一些使用上述代码的示例将不胜感激。

我用加载方法尝试了这个反序列化器,它仍然给出了同样的错误:

ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(KillCountRatio.class, new KillCountRatioDeserializer());
        mapper.registerModule(module);

我也尝试用这个注释 KillCountRatio class:

 @JsonDeserialize(using = KillCountRatioDeserializer.class)

这不起作用的原因是泛型在 Java 中的工作方式,您可能需要阅读一些关于 type erasure 的内容。

你试图告诉它它应该读取一个 Map,它的键是 Strings,它的值是 KillCountRatios,但是运行时版本看到的是它只是应该读取 Map(因为这是保留的所有信息)。由于 ObjectMapper 的默认行为是将未知的 JSON 对象读入 HashMap(在本例中,LinkedHashMap 以保留字段顺序),这正是会的。

要使 ObjectMapper 正确地将您的 JSON 对象反序列化为 KillCountRatios 对象,您必须编写自己的反序列化器(请参阅简短教程 here) .