Десериализовать JSON в коллекцию неизвестных типов - PullRequest
1 голос
/ 18 апреля 2011

Я пишу программу на Java, которая выполняет запросы к внешнему API, вызывая некоторые методы. Каждый из этих методов возвращает различную структуру JSON, и это также зависит от переданных параметров. Мой вопрос: есть ли способ десериализации строки ответа с помощью Gson без необходимости писать разные классы для каждого метода.

Если не Gson, какую другую библиотеку я могу использовать?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 10 июня 2011

Мой вопрос: есть ли способ десериализации строки ответа с использованием Gson без необходимости писать разные классы для каждого метода.

Да, есть.Если структура JSON, которую вы не хотите десериализовать в конкретный тип Java, является просто объектом, который содержит пары ключ-значение, где все значения являются примитивами JSON, тогда структуру можно просто десериализовать в Map<String, String>.

Обратите внимание, что Map<String, Object> не будет работать, так как он не предоставляет достаточно информации о типе для десериализации Gson.Gson будет просто создавать простые Object экземпляры для каждого значения - не String или Integer экземпляров, а просто простые Object экземпляры.Фактические значения в JSON не будут десериализованы.На первый взгляд кажется разумным, что Gson может быть улучшен для создания более специфичных для типа экземпляров для значений JsonPrimitive.Например, поскольку можно определить, является ли JsonPrimitive Boolean с помощью вызова isBoolean(), можно надеяться, что Gson просто создаст Boolean, но это не так - Gson просто создаетпустой и, вероятно, бесполезный Object.

Вот пример, демонстрирующий эту точку.

input.json Содержание:

{
  "one":"won",
  "too":22,
  "3":false
}

Foo.java:

import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    Type mapOfStringObjectType = new TypeToken<Map<String, String>>() {}.getType();
    Map<String, String> map = gson.fromJson(new FileReader("input.json"), mapOfStringObjectType);
    System.out.println(map);
  }
}

Вывод этого примера: {3=false, one=won, too=22}.

Если тип Map в примере изменен на HashMap<String, Object>как рекомендовано в другом ответе, тогда вывод становится {3=java.lang.Object@10b61fd1, one=java.lang.Object@24e2dae9, too=java.lang.Object@299209ea}, что, конечно, вероятно бесполезно.

Если по какой-то причине тип HashMap<String, Object> должен быть десериализован в , тообработка десериализации была бы необходима.

Если структура JSON не является простым набором пар ключ-значение, где значения - это все примитивы JSON, но включают значения, которые являются сложными типами, такими как объекты JSON, даже если это приемлемопреобразовать все значения в Strings, а затемТакже может потребоваться реализация пользовательской обработки десериализации.

Не стесняйтесь, перейдите к Списку проблем Gson и отправьте запрос на расширение для улучшенной десериализации примитива JSON для соответствующей конкретной Java Object типов или иметь простой механизм для преобразования любого значения - включая сложные типы JSON, такие как объекты и массивы, - в Map в String, так что пользовательская обработка десериализации, как описано выше, не потребуется.

1 голос
/ 18 апреля 2011

Вы должны написать другой класс, который бы представлял ответы от разных методов, если вы хотите использовать gson. Если ответ является простым ключом-значением, вы можете преобразовать ответ в HashMap<String,Object>, который будет действовать как «универсальный» класс для удовлетворения всех типов ответов в вашем случае использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...