2014-05-07 9 views
11

REST API mówię do reaguje na niektóre wnioski w strukturze, takie jak:Telling Retrofit do jakiej zmiennej powinien odwzorować określone pole json?

{ 
    "_links": { 
    "next": "NEXT_DATA_BLOCK_URL", 
    "prev": "PREV_DATA_BLOCK_URL", 
    "self": "CURRENT_DATA_BLOCK_URL" 
    }, 
    "RESPONSE_DATA_NAME": [ 
    { 
     ... DATA_FIELDS ... 
    } 
    ] 
} 

Gdzie RESPONSE_DATA_NAME "jest dane„nazwa”- zmienia się w zależności od żądanego wniosku. na przykład może to być "zespoły" lub "wiadomości".

Dlatego stworzyłem rodzajowe klasy z następujących członków:

public class PagedResponse<T> { 
    public PagingLinks _links; 
    public List<T> _data; 
} 

jest jakiś sposób mogę skonfigurować RestAdapter tak że będzie ona zawsze map „RESPONSE_DATA_NAME” do „_data” członka, nie jakie znaczenie ma nazwa pola?

Dzięki^_^

Odpowiedz

15

Korzystanie gson można opisywać swoje _data pole z @SerializedName. Parametr (wartość) tej adnotacji jest nazwą używaną podczas szeregowania i deseresyfikacji obiektów. Na przykład pole Java _ data jest reprezentowane jako JSON jako RESPONSE_DATA_NAME.

public class PagedResponse<T> { 

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

Dalsze zobaczyć doc


Jeśli chcesz kontrolować pole json potem trzeba napisać niestandardowy de-serializatora tak jak poniżej

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; 

    } 
} 

wreszcie analizować je

GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(PagedResponse.class, new CustomDeserializer()); 
Gson gson = gsonBuilder.create(); 

gson.fromJson(Your_JSON_STRING_HERE, PagedResponse.class); 
+0

Problemem jest nazwą pola zmienia się w zależności od wniosku (może być „drużyny” dla jednego wniosku lub "wiadomości" dla drugiej). Dlatego nie jest to rozwiązanie mojego problemu. Gdybym mógł użyć tej adnotacji wiele razy w zmiennej "_data", mogłem sobie poradzić, ale niestety nie jest to możliwe ... żadnych innych sugestii? =/ – iDaN5x

+0

następnie można napisać niestandardowy serializer i deklosalizacji, masz kontrolę w rękach –

+0

Chciałbym tego uniknąć, ponieważ jestem trochę leniwy ... Cóż, chyba nie mam innego wyboru ... mimo wszystko dziekuję! – iDaN5x

1

Tak I w końcu znalazłem rozwiązanie problemu ...

stworzyłem kostium de serializatora, który dodaje pole data do istniejącego JsonObject i kopiuje zawartość RESPONSE_DATA_NAME (co jest JsonArray). Następnie dokonuję serializacji w zwykłym trybie dzięki prostej konwersji w systemie GSON (gson.fromJson()).

To trochę głupie, ale działa = P

klasy DE-serializer za:

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);  
    } 
} 
Powiązane problemy