Вопрос по json, java – GSON: Как переместить поля в родительский объект

4

Я используюGoogle GSON преобразовать мой Java-объект в JSON.

В настоящее время я имею следующую структуру:

"Step": {
  "start_name": "Start",
  "end_name": "End",
  "data": {
    "duration": {
      "value": 292,
      "text": "4 min."
    },
    "distance": {
       "value": 1009.0,
       "text": "1 km"
    },
    "location": {
       "lat": 59.0000,
       "lng": 9.0000,
       "alt": 0.0
    }
  }
}

В настоящее времяDuration объект находится внутриData объект. Я хотел бы пропуститьData возразить и переместитьDuration возражать противStep объект, как это:

"Step": {
  "start_name": "Start",
  "end_name": "End",
  "duration": {
    "value": 292,
    "text": "4 min."
  },
  "distance": {
     "value": 1009.0,
     "text": "1 km"
  },
  "location": {
     "lat": 59.0000,
     "lng": 9.0000,
     "alt": 0.0
  }
}

Как я могу сделать это с помощью GSON?

РЕДАКТИРОВАТЬ: Я пытался использовать TypeAdapter для изменения класса Step.class, но в методе записи я не могу добавить свой объект продолжительности в JsonWriter.

Ваш Ответ

3   ответа
0

Столкнулся с той же проблемой. Ответ @ArjunShunkar указал мне правильное направление. Я исправил это, написав собственный Serializer, но немного по-другому:

public class StepSerializer implements JsonSerializer<Step> {
    @Override
    public JsonElement serialize(Step src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject step = new JsonObject();
        step.add ("start_name", context.serialize(src.start_name);
        step.add ("end_name",   context.serialize(src.end_name);

        JsonObject data = context.serialize(src.data).getAsJsonObject();
        data.entrySet().forEach(entry -> {
            step.add(entry.getKey(), entry.getValue());
        });

        return step;
    }
}

Это может быть улучшено далее, «имя_старки» и & quot; имя_конца & quot; реквизиты все еще жестко закодированы. Можно удалить, перейдя через набор записей для корневого объекта и исключив «данные»; там, оставляя только элемент, который должен быть развернут в жестком коде.

3

Вы, вероятно, можете сделать это, написав, а затем зарегистрировавпользовательский сериализатор заStepи убедившись, что внутри него вы работаетеDuration и т. д. вместоData.

// registering your custom serializer:
GsonBuilder builder = new GsonBuilder ();
builder.registerTypeAdapter (Step.class, new StepSerializer ());
Gson gson = builder.create ();
// now use 'gson' to do all the work

Код для пользовательского сериализатора ниже, я пишу на макушке. Он пропускает обработку исключений и может не скомпилироваться, а также замедляет такие вещи, как создание экземпляровGson несколько раз. Но это представляетkind of thing Вы хотите сделать:

class StepSerializer implements JsonSerializer<Step>
{
  public JsonElement serialize (Step src,
                                Type typeOfSrc,
                                JsonSerializationContext context)
    {
      Gson gson = new Gson ();
      /* Whenever Step is serialized,
      serialize the contained Data correctly.  */
      JsonObject step = new JsonObject ();
      step.add ("start_name", gson.toJsonTree (src.start_name);
      step.add ("end_name",   gson.toJsonTree (src.end_name);

      /* Notice how I'm digging 2 levels deep into 'data.' but adding
      JSON elements 1 level deep into 'step' itself.  */
      step.add ("duration",   gson.toJsonTree (src.data.duration);
      step.add ("distance",   gson.toJsonTree (src.data.distance);
      step.add ("location",   gson.toJsonTree (src.data.location);

      return step;
    }
}
этоreally зависит. Покажите пример с двумя дополнительными полями, и я посмотрю, что я могу придумать. Предостережение: мой ответ основан на документации Gson. Я никогда раньше не делал таких странных вещей.
Благодарю. Есть ли способ создатьstep переменная из шага src и просто удалите его объект данных? Если это возможно, мне не нужно было бы снова добавлять начальное и конечное имя. dhrm
@DennisMadsen - я обновил свой ответ, чтобы отразить ваши изменения. Удачи.
Мне нужно толькоserialize, такdeserialize не важно. Выше было просто пример моей структуры. Фактически мой объект данных содержит дополнительные поля, которые необходимо включить вtoJsonTree, Любая подсказка, как я могу это сделать? dhrm
Я обновил свой вопрос дополнительными полями внутри объекта данных. dhrm
0

Я не думаю, что есть прекрасный способ сделать это в gson. Может быть, получить объект java (Map) из исходного json, удалить данные, указать продолжительность и сериализовать в json:

Map initial = gson.fromJson(initialJson);

// Replace data with duration in this map
Map converted = ...

String convertedJson = gson.toJson(converted);

Похожие вопросы