I'm trying to build an app using an external API (I have no control over the JSON that I'm getting and can't change it). I can't find how to pares something like that, as it is highly un orthodox in its structure:
{
"1":{
"id":1
"name:"name1"
"books":[{BOOK},{BOOK},{BOOK}]
},
"2":{
"id":2
"name:"name2"
"books":[{BOOK},{BOOK},{BOOK}]
},
"3":{
"id":3
"name:"name3"
"books":[{BOOK},{BOOK},{BOOK}]
},
"4":{
"id":4
"name:"name4"
"books":[{BOOK},{BOOK},{BOOK}]
},
....
}
A little explanation about the structure: 1. The first level is the categories of the book. 2. In each book in the array there is a field that points to the category 3. As you can see, the id is the same as the key of the category object
The Task: I need to parse this into: 1. All the categories (I've build a Category Class and a CategoryResponse Class with a list of categories) 2. I Need to parse the Array of Books in each category
Category Class:
public class Category {
@SerializedName("Name")
private String name;
@SerializedName("Id")
private Integer id;
@SerializedName("OrderKey")
private Integer orderKey;
@SerializedName("Books")
private List<Book> books = new ArrayList<Book>();
public Category(String name, Integer id, Integer orderKey, List<Book> books) {
this.name = name;
this.id = id;
this.orderKey = orderKey;
this.books = books;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}
CategoryResponse Class:
public class CategoryResponse {
@SerializedName("")
private List<Category> categories;
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
}
I have a book class also.... This is not the problem.
ApiClient Class:
public static Retrofit getClient() {
if(retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
ApiInterface:
public interface ApiInterface {
@GET("Books/GetBooks")
Call<CategoryResponse> getCategories();
}
The Fragment for the Categories and Books (In onCreateView method):
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<CategoryResponse> call = apiService.getCategories();
call.enqueue(new Callback<CategoryResponse>() {
@Override
public void onResponse(Call<CategoryResponse> call, Response<CategoryResponse> response) {
categories = response.body().getCategories();
Log.d(TAG, "Number of categories recieved: " + categories.size());
}
@Override
public void onFailure(Call<CategoryResponse> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
return inflater.inflate(R.layout.fragment_books, container, false);
}
As you can see, There are two problems over here: 1. I don't know what to wrote in @SerializedName in CategoryResponse 2. The response comes back 200 (Good) but with no categories as there is not way i can find how to pares the JSON with no root element and not a list, just an object with objects but each objects is of the same type (a Category with fields and an array of books)
I can't find the solution in Android for this (In IOS it was very simple but just can't find how to do it in Android)
The App crashes on the Log for the success response because categories is null (of course it is, i know it is wrong, as there is no root to parse from, but can't fix it)
10x