2013-01-17 110 views
13

我正面临一个问题,有时Json响应会返回一个对象数组,有时会自动对象,我们如何在响应类中动态处理。 在当前如:结果有时会对象如何使用Gson动态处理json响应数组/对象

"\"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()); 

请帮助...

谁能给通过使用不同的罐子来实现这一目标有什么建议?

+0

这样的服务器的实现是真实的不好之一。这是你的后端? – Evos

+0

其客户端,我从服务器收到此响应.. – Rockin

+0

如果服务器返回一个对象数组,它总是包含一个对象或可以包含多个对象?如果它是一个数组,你会处理它的每一个元素? – dstronczak

回答

16

我发现了一个解决方案,我觉得分享这个..代码会自动转换..如果例外响应是arraylist在响应类....然后如果对象来响应然后添加到arraylist否则如果数组列表将采用相同的列表。 我们需要hook在从Json调用之前更改响应。

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) 
+0

它给在TypeAdapter错误 typeAdapter = null;为 .. 您可以通过修改像 公共类ArrayAdapterFactory 实现TypeAdapterFactory类签名解决此问题{ –

+0

com.google.gson.internal。$ GSON $类型$ ParameterizedTypeImpl不能转换为java.lang.Class中 \t在使用上述示例进行映射时,我正在获取错误 –

3

您需要编写一个自定义的反序列化器,检查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); 

    } 
} 

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