Как десериализовать файл JSON (используя Google JSON), состоящий из того же имени ключа, но другого типа? - PullRequest
0 голосов
/ 17 апреля 2020

Рассмотрим следующий JSON Файл:

{
    "version": "1.0",
    "firstData": {
        "meta": "this is string",
        "version": "1"
    },
    "SecondData": {
        "meta": ["string1", "string2", "string3"],
        "version": "1"
    },
    "ThirdData": {
        "meta": true,
        "version": "1"
    },
    "FourthData": {
        "meta": [true, false, false, true],
        "version": "1"
    },
    "FifthData": {
        "meta": [{
            "meta": "string",
            "version": "2"
        },
        {
            "meta": ["string1","string2"],
            "version": "2"
        }]
        "version": "1"
    }

}

Как видно, атрибут «meta» имеет другой тип данных, иногда это String, иногда ArrayOfString, иногда Boolean et c.

Поскольку мой файл JSON содержит несколько данных, я хочу, чтобы он имел следующую структуру:

class information
{
String version;
HashMap<String,Data> details;
}
class Data
{
 variable meta;
String version;
}

Как создать соответствующий POJO и десериализовать его с помощью Google GSON?

1 Ответ

1 голос
/ 17 апреля 2020

Просто определите ваш meta как JsonElement. Тогда у вас будут методы сортировки, такие как: getAsString, getAsBoolean, getAsJsonObject, getAsJsonArray, ..., а также вы сможете снова десериализовать его после того, как узнаете, что это за тип.

Таким образом, ваш класс может выглядеть следующим образом:

public class SomeClass {
    private int version;
    private JsonElement meta;

    //getters and setters and other stuff
}

Редактировать: дополнительная проработка и реализация

Определить два класса: GeneralItem и GeneralData

class GeneralItem
{
    public final int version;
    public final JsonElement meta;
}
class GeneralData
{
    public final String version;
    public final Map<String, GeneralItem> items;

    public GeneralData(String version, Map<String, GeneralItem> items)
    {
        this.version = version;
        this.items = items;
    }
}

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

class GeneralDataDeserializer implements JsonDeserializer<GeneralData>
{

    @Override
    public GeneralData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
        final JsonObject object = json.getAsJsonObject();
        final String version = object.get("version").getAsString();
        object.remove("version");
        HashMap<String, GeneralItem> items = new HashMap<>(object.size());
        for (Map.Entry<String, JsonElement> item : object.entrySet())
            items.put(item.getKey(), context.deserialize(item.getValue(), GeneralItem.class));
        return new GeneralData(version, items);
    }
}

Наконец, регистрируем десериализатор в нашем экземпляре gson и получаем данные:

final Gson gson = new GsonBuilder()
        .registerTypeAdapter(GeneralData.class, new GeneralDataDeserializer())
        .create();

final String json = "your json here";
final GeneralData data = gson.fromJson(json, GeneralData.class);
System.out.println(data.items.get("firstData").meta.getAsString());
//other parts you want

(Обратите внимание, что конструкторы, геттеры и сеттеры, проверка ошибок и т. д. c. удалены для краткости)

...