告诉改造应该映射某个json字段的变量?

时间:2014-05-07 17:26:39

标签: json gson retrofit

我正在谈论的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'成员,无论字段名称实际是什么?

谢谢^ _ ^

2 个答案:

答案 0 :(得分:19)

使用gson,您可以使用@SerializedName注释_data字段。此批注的参数(值)是序列化和反序列化对象时要使用的名称。例如,Java字段_ data在JSON中表示为RESPONSE_DATA_NAME

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);

答案 1 :(得分:1)

所以我终于找到了问题的解决方案......

我创建了一个服装反序列化器,它将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);      
    }
}