Изменение двух имен файлов во время десериализации JSON в JAVA

у меня есть json-файл

{"apple" : [
        {
            "first"    : 3,
            "second"    : 5,

        }
      ],
"orange" : [
        {
            "fst"    : 7,
            "snd"    : 8,

        }
      ],
}

вспомогательный класс для десериализации


public class Helper {

    private int num1;

    private int num2;

    public Helper(Helper other) {
        this.num1 = other.num1;
        this.num2 = other.num2;
    }

    public int getNum1() {
        return this.num1;
    }

    public int getNum2() {
        return this.num2;
    }
}

Класс Java для десериализации, в котором мне нужно изменить ключи JSON, чтобы они были совместимы с именами экземпляров класса Helper.

public class MyDesClass {

    @SerializedName(value = "apple.first", alternate = "apple.num1")
    @SerializedName(value = "apple.seconds", alternate = "apple.num2")
    private final Helper[] apple;

    public MyDesClass(Helper[] apple) {
        this.apple = apple;
    }
    
}          

А также внутри main.java у меня есть:

/* .... */
        Reader f = new FileReader( PATH_TO_THE_JSON_FILE);
        Gson gson = new Gson();
        GameBoard gameBoard = gson.fromJson(f, MyDesClass.class);
/* .... */

Мой вопрос: как я могу преобразовать два значения (например, first и second) одновременно (например, в num1 и num2 здесь) в MyDesClass? В настоящее время я получаю ошибку SerializedName is not a repeatable annotation type.


person vortex    schedule 21.06.2020    source источник


Ответы (1)


Вам нужно использовать @SerializedName в классе Helper (и при необходимости обновить MyDesClass):

public class Helper {

    @SerializedName(value = "first" alternate={"num1","fst"})
    private int num1;

    @SerializedName(value = "second" alternate={"num2","snd"})
    private int num2;

    public Helper(Helper other) {
        this.num1 = other.num1;
        this.num2 = other.num2;
    }

    public int getNum1() {
        return this.num1;
    }

    public int getNum2() {
        return this.num2;
    }
}

Чтобы соответствовать обновленному JSON, MyDesClass необходимо иметь еще одно поле orange:

public class MyDesClass {

    @SerializedName("apple")
    private final Helper[] apple;

    @SerializedName("orange")
    private final Helper[] orange;

    public MyDesClass(Helper[] apple, Helper[] orange) {
        this.apple = apple;
        this.orange = orange;
    }
// ...    
} 
person Alex Rudenko    schedule 21.06.2020
comment
спасибо за ваше решение. Однако ключ JSON может быть переменным. извините, если было непонятно. Я расширил файл JSON в своем примере для пояснения. Итак, если десериализация в классе Helper — единственный вариант, то есть ли способ сделать ключ value в переменной @SerializedName? - person vortex; 22.06.2020
comment
Я обновил ответ для вашего обновленного JSON - требуется еще одно поле orange. Однако возможно, что вместо этого вы хотели применить @SerializedName к своему полю apple. Или вообще использовать карту <String, List<Helper>> вместо MyDesClass. - person Alex Rudenko; 22.06.2020
comment
Большое спасибо за ваш ответ, он решил большую часть моих проблем. Только вот еще вопрос. В моей исходной задаче первый ключ в JSON — это объект, а второй ключ — это массив объектов. В JSON большинство записей имеют порядок key1: Object, key2:[Object1, ...]. Однако в некоторых случаях порядок обратный key1: [Object1, ...], key2:Object, и эти записи не десериализуются. Есть мысли по исправлению этого? - person vortex; 22.06.2020
comment
Возможно, вам придется проверить ответ здесь - person Alex Rudenko; 22.06.2020