2013-01-17 18 views
13

ile dinamik olarak nasıl işleyebilirim Bir sorunla karşı karşıyayım, bazen Json yanıtı, nesne sınıfını döndürür, bazen nesne kendini, yanıt sınıfında dinamik olarak nasıl başa çıkabiliriz. Geçerli Örn olarak : Sonuçlar bazen Gson response dizisi/nesnesini Gson

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

nesnelerin

dizisi alır ve bazen kendisini

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

Örn nesne:

biz bu işleyebilir nasıl?

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

Lütfen yardımcı ...

kimse bunu başarmak için farklı kavanozları kullanarak herhangi bir öneri verebilir misiniz?

+0

Böyle sunucu gerçekleşme gerçekten iyi biri değil diyoruz. Senin arka ucun mu? – Evos

+0

istemcisi, bu yanıtı sunucudan aldım .. – Rockin

+0

Sunucu bir nesne dizisi döndürürse, her zaman tek bir nesne içerir veya birden çok içeremez? Eğer bir dizi varsa, onun her bir öğesiyle mi işlem yapıyorsunuz? – dstronczak

cevap

16

Bunun için bir çözüm buldum, bunu paylaşmak istediğimi hissettim .. Kod otomatik olarak dönüşecektir .. yanıtı yanıt sınıfında arraylist ... eğer nesne yanıt olarak geliyorsa o zaman arraylist'e ekleyin. arraylist aynı listeyi alacak. Kancanın cevabını değiştirmemiz gerekiyor, çünkü Json'dan arama yapıyor.

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

sonra sadece

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

TypeAdapter typeAdapter = null; için .. Sen TypeAdapterFactory uygulayan ArrayAdapterFactory kamu sınıf gibi sınıf imzasını değiştirerek bu sorunu çözebilirsiniz { –

+0

com.google.gson.internal. $ GSON $ Türleri $ ParameterizedTypeImpl java.lang.Class \t için döküm edilemez Yukarıdaki örnek kullanılarak eşleştirilirken hata alıyorum –

3

JSON'da results türünü denetleyen özel bir desperizatör yazmanız ve sonra buna göre davranmanız gerekir.

POJO'nuz results için bir dizi içerecektir ve gelen JSON'unuzda tek bir nesne varsa bunu düzeltmeniz gerekecektir. elbette,

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

    } 
} 

Veya, sunucuyu düzeltmek: Tek yönlü sonra JSON değiştirmek bu serisini etmektir. Bu sorunu önlemek için her zaman bir dizi döndürmelidir.