Ответ 1
Причина, по которой Nishant answer работает, заключается в том, что конструктор по умолчанию Gson позволяет использовать все типы материалов по умолчанию, которые вам в противном случае пришлось бы вручную использовать с помощью GsonBuilder.
Из JavaDocs:
Создает объект Gson с настройкой по умолчанию. Конфигурация по умолчанию имеет следующие настройки:
- JSON, генерируемый методами toJson, находится в компактном представлении. Это означает, что все ненужное белое пространство удалено. Вы можете изменить это поведение с помощью GsonBuilder.setPrettyPrinting().
- Сгенерированный JSON пропускает все поля, которые являются нулевыми. Обратите внимание, что нули в массивах сохраняются как есть, так как массив является упорядоченным списком. Более того, если поле не является нулевым, но его сгенерированный JSON пуст, поле сохраняется. Вы можете настроить Gson для сериализации нулевых значений, установив GsonBuilder.serializeNulls().
- Gson предоставляет сериализацию и десериализацию по умолчанию для Enums, Map, java.net.URL, java.net.URI, java.util.Locale, java.util.Date, java.math.BigDecimal и java.math.BigInteger классы. Если вы предпочитаете изменять представление по умолчанию, вы можете сделать это, зарегистрировав адаптер типа через GsonBuilder.registerTypeAdapter(Тип, Объект).
- Формат даты по умолчанию такой же, как java.text.DateFormat.DEFAULT. Этот формат игнорирует миллисекундную часть даты во время сериализации. Вы можете изменить это, вызывая GsonBuilder.setDateFormat(int) или GsonBuilder.setDateFormat(String).
- По умолчанию Gson игнорирует аннотацию com.google.gson.annotations.Expose. Вы можете включить Gson для сериализации/десериализации только тех полей, помеченных этой аннотацией через GsonBuilder.excludeFieldsWithoutExposeAnnotation().
- По умолчанию Gson игнорирует com.google.gson.annotations.Since с аннотацией. Вы можете включить Gson для использования этой аннотации через GsonBuilder.setVersion(double).
- Политика именования полей по умолчанию для вывода Json такая же, как и в Java. Таким образом, поле версии versionNumber класса Java будет выводиться как "versionNumber @" в Json. Те же правила применяются для отображения входящих Json в классы Java. Вы можете изменить эту политику с помощью GsonBuilder.setFieldNamingPolicy(FieldNamingPolicy).
- По умолчанию Gson исключает переходные или статические поля из соображений сериализации и десериализации. Вы можете изменить это поведение через GsonBuilder.excludeFieldsWithModifiers(int).
ОК, теперь я вижу, в чем проблема. Серийный анализатор карт по умолчанию, как вы ожидали, не поддерживает вложенные карты. Как вы можете видеть в этот исходный фрагмент из DefaultTypeAdapters (особенно если вы перейдете к отладчику) переменная childGenericType
установлена в тип java.lang.Object
по какой-то загадочной причине, поэтому тип времени выполнения никогда не анализируется.
Два решения, я думаю:
- Внедрить собственный сериализатор/десериализатор карт
-
Используйте более сложную версию вашего метода, примерно так:
public String toJSON(){ final Gson gson = new Gson(); final JsonElement jsonTree = gson.toJsonTree(General, Map.class); final JsonObject jsonObject = new JsonObject(); jsonObject.add("General", jsonTree); return jsonObject.toString(); }