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

{
  "_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, независимо от того, какое имя поля на самом деле?

Спасибо ^ _ ^

12
iDaN5x 7 Май 2014 в 21:26

2 ответа

Лучший ответ

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

public class PagedResponse<T> {

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

См. Также документ


Если вы хотите управлять полем 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);
20
Asif Bhutto 7 Май 2014 в 18:51

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

Я создал десериализатор костюмов, который добавляет поле 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);      
    }
}
1
iDaN5x 9 Май 2014 в 21:42