Скачайте "Дооснастить" какой переменной она должна отображать определенное поле json?

API REST, с которым я говорю, отвечает на некоторые запросы в структуре как таковой:

{
  "_links": {
    "next": "NEXT_DATA_BLOCK_URL",
    "prev": "PREV_DATA_BLOCK_URL",
    "self": "CURRENT_DATA_BLOCK_URL"
  },
  "RESPONSE_DATA_NAME": [
    {
      ... DATA_FIELDS ...
    }
  ]
}

Где "RESPONSE_DATA_NAME" - это "имя" данных - изменяется в соответствии с желаемым запросом. например, это могут быть "команды" или "сообщения".

Поэтому я создал общий класс со следующими членами:

public class PagedResponse<T> {
  public PagingLinks _links;
  public List<T> _data;
}

Можно ли настроить мой RestAdapter так, чтобы он всегда отображал 'RESPONSE_DATA_NAME' члену '_data', независимо от того, что на самом деле имя поля?

Спасибо ^ _ ^

Ответ 1

Используя gson, вы можете аннотировать ваше поле _data с помощью @SerializedName. Параметр (значение) этой аннотации - это имя, которое будет использоваться при сериализации и десериализации объектов. Например, поле Java _ data представляется как RESPONSE_DATA_NAME в JSON.

public class PagedResponse<T> {

    public PagingLinks _links;
    @SerializedName(value="RESPONSE_DATA_NAME")
    public List<T> _data;
}

Далее см. doc


Если вы хотите управлять полем json, вам нужно написать собственный де-сериализатор, как показано ниже

public class CustomDeserializer implements JsonDeserializer<PagedResponse> {

    @Override
    public PagedResponse deserialize(final JsonElement json,
            final Type typeOfT, final JsonDeserializationContext context)
            throws JsonParseException {

        Gson gson = new Gson();
        PagedResponse pagedResponse = new PagedResponse<>();
        List list = new ArrayList<>();

        pagedResponse = gson.fromJson(json, PagedResponse.class);

        Type listType = new TypeToken<List>() {}.getType();

        Set<Entry<String, JsonElement>> enteries = json.getAsJsonObject().entrySet();
        for (Entry<String, JsonElement> entry : enteries) {
            JsonElement jsonElement = (JsonElement) entry.getValue();
            if (jsonElement.isJsonArray()) {
                list.add(gson.fromJson(jsonElement, listType));
            }
        }
        pagedResponse.set_data(list);
        return pagedResponse;

    }
}

наконец проанализируйте его

 GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(PagedResponse.class, new CustomDeserializer());
Gson gson = gsonBuilder.create();

gson.fromJson(Your_JSON_STRING_HERE, PagedResponse.class);

Ответ 2

Итак, я наконец нашел решение проблемы...

Я создал декоризатор костюма, который добавляет поле data к существующему JsonObject и копирует содержимое RESPONSE_DATA_NAME (которое является JsonArray). Затем я сериализую его с помощью простого преобразования GSON (gson.fromJson()).

Это немного глупо, но работает = P

Класс де-сериализатора:

public class PagedResponseDeserializer implements JsonDeserializer<PagedResponse> {

    @Override
    public PagedResponse deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {

        Gson gson = new Gson();
        JsonElement value = null;
        JsonObject jsonObject = json.getAsJsonObject();     

        Iterable<Entry<String,JsonElement>> entries = jsonObject.entrySet();
        for (Entry<String, JsonElement> entry : entries) {
            value = entry.getValue();
            if (value.isJsonArray()) break;
        }

        jsonObject.add("data", value);

        return gson.fromJson(jsonObject, typeOfT);      
    }
}