JSON Джексон читает значения класса hashmaps как LinkedHashMap - PullRequest
0 голосов
/ 10 июня 2019

Я сохраняю счет (класс KillcountRatio) в имя (String) в HashMap, которое я сохраняю с помощью Jackson JSON, но при загрузке сохраненного файла json невозможно преобразовать значение класса KillCountRatio, хранящееся в HashMap с определенным ключом для KillCountRatio, он дает

java.util.LinkedHashMap не может быть приведен к KillCountRatio

потому что значение, хранящееся в HashMap, больше не является KillCountRatio, а является LinkedHashMap.

Не уверен, что попробовать.

Вот класс KillCountRatio:

public final class KillCountRatio {

    private int killCount;

    private int deathCount;

}

Вот хэш-карта, в которой вышеупомянутое сохраняется и получает ключ String, а затем сохраняется с помощью 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 следующим образом:

 @JsonDeserialize(using = KillCountRatioDeserializer.class)

1 Ответ

0 голосов
/ 10 июня 2019

Причина, по которой это не работает, заключается в том, как дженерики работают в Java, возможно, вы захотите немного прочитать о стирании типа .

Вы пытаетесь сказать ему, что он должен прочитать Map с ключами Strings и значениями KillCountRatios, но версия во время выполнения видит, что она просто должна прочитать Map (потому что это вся информация, которая сохраняется).А поскольку поведение по умолчанию ObjectMapper заключается в считывании неизвестного объекта JSON в HashMap (в данном случае LinkedHashMap для сохранения порядка полей), это именно то, что он будет делать.

Чтобы ObjectMapper правильно десериализовал ваш объект JSON в KillCountRatios объект, вам нужно написать собственный десериализатор (см. Краткое руководство здесь ).

...