Nano Hash - криптовалюты, майнинг, программирование

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

Рассмотрим следующий файл 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 и т. д.

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

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

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


  • Кроме того, есть несколько вещей, которые неясны по этому поводу, может ли это перейти на любой уровень вложенности для элемента meta, это соображение? Я вижу, что пятый элемент - это объект json, который также имеет мета, означает ли это вложенность? 17.04.2020

Ответы:


1

Просто определите свой 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

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

17.04.2020
  • Привет, Мохаммад. Спасибо за ответ, но я его не понял. Можете ли вы уточнить это, пожалуйста, или, возможно, поделитесь решением, используя GSON 17.04.2020
  • Это ГСОН! вам нужно просто определить ваши firstData, SecondData, ... как SomeClass (назовите их как угодно), а затем они будут десериализованы, а затем вы можете вызвать meta.getAsString() для firstData или meta.getAsJsonArray() для SecondData. Дайте мне знать, если вы хотите больше примеров. 17.04.2020
  • Да, правильно, но что, если у меня есть firstData, SecondData.......ThousandthData.. Вот почему вместо создания такого количества классов я хочу создать карту строк для одной структуры класса, как описано выше, может ты мне в этом помогаешь? 17.04.2020
  • Я предоставил дополнительную информацию, если вы хотите проверить. @кодер 17.04.2020
  • У меня есть одно сомнение, мета будет храниться как JSONElement. Если это массив строк, он не будет храниться как массив строк. Есть ли способ сохранить их как соответствующий тип данных? 17.04.2020
  • Вы можете изменить тип meta на Object. Затем для примитивных типов gson, таких как int, String, boolean и т. д., он будет заполнен ожидаемым значением с этим типом java; для дочерних массивов он будет заполнен ArrayList этих примитивных типов, а для объектов (таких как FirfthData) meta будет Map из String этих примитивных типов. @кодер 17.04.2020
  • Да, мне удалось сохранить исходный тип. Хотя, что, если мета в основном представляет собой массив объектов мета? проверьте файл JSON FifthData выше ^ 17.04.2020
  • Это даст вам список карт. Если вы хотите получить объекты, вы можете выполнить десериализацию вручную и указать тип. Если для вас возникает вопрос о десериализации ArrayList метаданных, вы можете выполнить поиск десериализации универсальных типов с помощью gson. 17.04.2020
  • Код, который вы написали, обрабатывает все типы метаданных, кроме ArrayList‹Meta›? Как с этим справиться? Не могли бы вы отредактировать свой ответ и добавить туда решение? Я пытался, но я не мог решить это! 20.04.2020
  • Проверьте это: stackoverflow .com/questions/12384064/ 20.04.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..