【问题标题】:How to dynamically handle json response array/object using Gson如何使用 Gson 动态处理 json 响应数组/对象
【发布时间】:2012-12-31 15:47:15
【问题描述】:

我面临一个问题,有时Json响应返回一个对象数组,有时是对象本身,我们如何在响应类中动态处理。 在当前的 eg :results 有时会得到一个对象数组

 "\"results\": " +
            "[{" +

有时是对象本身

 "\"results\": " +
            "{" +

例如:

我们该如何处理?

Gson gson = new Gson();
    SearchResponse response=new SearchResponse();
    response= gson.fromJson("{" +
            "\"completed_in\": 0.047," +
            "\"max_id\": 291771567376039936," +
            "\"max_id_str\": \"291771567376039936\"," +
            "\"next_page\": \"?page=2&max_id=291771567376039936&q=javacodegeeks\"," +
            "\"page\": 1," +
            "\"query\": \"javacodegeeks\"," +
            "\"refresh_url\": \"?since_id=291771567376039936&q=javacodegeeks\"," +
            "\"results\": " +
            "{" +
            "\"created_at\": \"Thu, 17 Jan 2013 04:58:57 +0000\"," +
            "\"from_user\": \"hkokko\"," +
            "\"from_user_id\": 24726686," +
            "\"from_user_id_str\": \"24726686\"," +
            " \"from_user_name\": \"Hannu Kokko\"," +
            " \"geo\": null," +
            "\"id\": 291771567376039936," +
            "\"id_str\": \"291771567376039936\"," +
            "\"iso_language_code\": \"en\"," +
            " \"metadata\": {" +
            "\"result_type\": \"recent\"}," +
            "\"profile_image_url\": \"hjh\"," +
            "\"profile_image_url_https\": \"kkj\"," +
            "\"source\": \"<a href="hj;\"," +
            "\"text\": \"Continuous Deployment: Are You Afraid It Might Work? jh\"," +
            "\"to_user\": null," +
            "\"to_user_id\": 0," +
            "\"to_user_id_str\": \"0\"," +
            "\"to_user_name\": null" +
            " }," +
            "\"results_per_page\": 15," +
            "\"since_id\": 0," +
            "\"since_id_str\": \"0\"" +
            "}", SearchResponse.class);
    System.out.println(response.toString());

请帮助...

任何人都可以通过使用不同的 jar 来实现这一点提供任何建议吗?

【问题讨论】:

  • 这样的服务器实现实在是不好。这是你的后端?
  • 它的客户端,我从服务器收到这个响应..
  • 如果服务器返回一个对象数组,它总是包含一个对象还是可以包含多个对象?如果它是一个数组,你会处理它的每个元素吗?

标签: java android gson


【解决方案1】:

我找到了一个解决方案,我想分享这个..代码将自动转换..如果例外响应是响应类中的arraylist..然后如果对象响应然后添加到arraylist,否则如果arraylist它将采用相同的列表。 我们需要在调用 fromJson 之前钩子更改响应。

public class ArrayAdapter<T> extends TypeAdapter<List<T>> {
    private Class<T> adapterclass;

    public ArrayAdapter(Class<T> adapterclass) {

        this.adapterclass = adapterclass;
    }

    public List<T> read(JsonReader reader) throws IOException {


        List<T> list = new ArrayList<T>();

        Gson gson = new Gson();

        if (reader.peek() == JsonToken.BEGIN_OBJECT) {

            T inning = (T) gson.fromJson(reader, adapterclass);
            list.add(inning);

        } else if (reader.peek() == JsonToken.BEGIN_ARRAY) {

            reader.beginArray();
            while (reader.hasNext()) {
                T inning = (T) gson.fromJson(reader, adapterclass);
                list.add(inning);
            }
            reader.endArray();

        } else {
            reader.skipValue();
        }

        return list;
    }

    public void write(JsonWriter writer, List<T> value) throws IOException {

    }

}

public class ArrayAdapterFactory implements TypeAdapterFactory {

  @SuppressWarnings({ "unchecked" })
  @Override
  public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {

      ArrayAdapter typeAdapter = null;
      try {
          if (type.getRawType() == List.class)
          {

              typeAdapter = new ArrayAdapter(
                      (Class) ((ParameterizedType) type.getType())
                              .getActualTypeArguments()[0]);
          }
      } catch (Exception e) {
          e.printStackTrace();
      }

      return typeAdapter;
}

然后打电话

 Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
 SearchResponse response;
 esponse= gson.fromJson("your json string", SearchResponse.class)

【讨论】:

  • 它在 TypeAdapter 处给出错误 typeAdapter = null;对于 .. 您可以通过修改类签名来解决此问题,例如 public class ArrayAdapterFactory implements TypeAdapterFactory {
  • com.google.gson.internal.$Gson$Types$ParameterizedTypeImpl cannot be cast to java.lang.Class at am get error while mapping using above example
【解决方案2】:

您需要编写一个自定义反序列化程序,检查 JSON 中 results 的类型,然后采取相应措施。

您的 POJO 将包含 results 的数组,如果您传入的 JSON 只有一个对象,您需要修复它。一种方法是修改 JSON 然后反序列化它:

class SearchResponseDeserializer implements JsonDeserializer<SearchResponse> {
  public SearchResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {

    if (json.getAsJsonObject().get("results").isJsonObject()) {
      //modify JSON: change results to be an array
      // ...
    }

    return new Gson().fromJson(json, SearchResults.class);

  }
}

当然,或者修复服务器。它应该总是返回一个数组以避免这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多