Reputation: 7527
The server currently returns a json which looks like the json given below, it contains a field called data
which is an array of arrays with each array having multiple objects and each object having a key called item_type
. The key item_type
allows me to figure out exactly what type of object it is so that I can cast it accordingly in java but I am unable to read the item_type
field.
{
"page":1,
"data":[
[
{
"id":1,
"name":"xyz",
"item_type":1
}
],
[
{
"cid":1,
"item_type":2
}
],
[
{
"item":1,
"item_type":3
}
]
]
}
The retrofit interface is like so
@GET("Search")
Observable<SearchResults> search(@Query(ParamsHolder.GET_QUERY)
String query, @Query(ParamsHolder.GET_PAGE) int page);
where the SearchResults
class looks like this
public class SearchResults {
int page;
List<List<Object>> data;
public int getPage() {
return page;
}
public List<List<Object>> getData() {
return data;
}
}
I am able to fetch the data fine but I need to read the objects that are inside each list. In order to do that I used the following code
public class SearchItem {
int item_type;
public int getItemType() {
return item_type;
}
}
List<List<Object>> data = objects.getData();
for (int i = 0; i < data.size(); i++) {
List<Object> list = data.get(i);
for (int j = 0; j < list.size(); j++) {
SearchItem item = (SearchItem) list.get(i);
Log.d("search", " json=" + list.get(j).toString());
Log.d("search", " item=" + item.toString() + " type=" + item.getItemType());
}
}
I created a dummy SearchItem
class which I assumed would let me typecast the Object
type so I could read the item_type
which would let me know exactly the type of object this is.
It throws an error com.google.gson.internal.LinkedTreeMap cannot be cast to in.example.models.SearchItem
The end goal here it to be able to cast each object in the array to the correct type and the only way I can do that is by reading the item_type
key in the object
Upvotes: 2
Views: 133
Reputation: 1317
use Response as a return type in your interface retrofit function as shown below
@GET("Search")
Observable<Response<ResponseBody>> search(@Query(ParamsHolder.GET_QUERY)
String query, @Query(ParamsHolder.GET_PAGE) int page);
this way you can retrieve the full json body and you have now full control on how parse the data based on item_type
so basically you call function response.body().string()
to get the json body
and than you parse manually like shown below:
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response.body().string());
JSONArray jsonArray = jsonObject.getJSONArray("data");
//looping through the data array
for(int i = 0;i<jsonArray.length();i++){
JSONArray childArr = jsonArray.getJSONArray(i);
//looping through current child array inside data
for(int j = 0;j<childArr .length();j++){
JSONObject nestedChildObj =childArr.getJSONObject(j);
//now i have access to item_type
int item_type = nestedChildObj .getInt("item_type")
//now you can use gson to parse the nestedChildObj based
//on item_type or manually do the parsing
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Upvotes: 1
Reputation: 399
Use Gson to directly parse the response
Update SearchResults
public class SearchResults {
int page;
List<List<SearchItem>> data;
public int getPage() {
return page;
}
public List<List<SearchItem>> getData() {
return data;
}
}
You can access item_type like this
searchResult.getData.get(i).get(0).item_type
Upvotes: 1