While trying to parse json in android, some of the most common errors that you might have come across are :
- expected begin_array but was begin_object
- expected begin_object but was begin_array
- expected a string but was begin_object
- expected begin_object but was string
- expected a string but was begin_array
- expected begin_array but was string
These error messages are thrown by gson. Have you ever wondered what these errors actually mean ? Well like it suggests you are not expecting for the required json format that is present in your endpoint(backend)/json
For example,
expected begin_array but was begin_object
Here you are expecting an array from your appside but infact your endpoint is returning an object. In this tutorial, we will be discussing further in detail with different json structures and how they can be parsed using retrofit 2.
Suppose you have a json object response like the following :
Add these dependencies in your app's build.gradle file
Add these dependencies in your app's build.gradle file
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
Case 1 : Parsing a json object response
{ "username":"jon", "email":"jon@email.com" }
Here we have a json object since its of the form {...}
First of all, goto http://www.jsonschema2pojo.org/ and create a model class for the json response like this one
JsonResponse.java
public class JsonResponse { @SerializedName("username") @Expose private String username; @SerializedName("email") @Expose private String email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Retrofit 2 code
Retrofit retrofit = new Retrofit.Builder() .baseUrl("base_url/") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestInterface request = retrofit.create(RequestInterface.class); Call<JsonResponse> call = request.getJSON(); call.enqueue(new Callback<JsonResponse>() { @Override public void onResponse(Call<JsonResponse> call, Response<JsonResponse> response) { } @Override public void onFailure(Call<JsonResponse> call, Throwable t) { Log.d("Error",t.getMessage()); } });
here, GsonConverterFactory automatically maps the JSON data to your Java objects which makes a lot of your work easier
RequestInterface.java
public interface RequestInterface { @GET("your_endpoint") Call<JsonResponse> getJSON(); }
Since its a json object response, we can fetch it like Call<JsonResponse> as mentioned above, but what if it is a json array response? We will discuss this below in case 2
You may also take look at this tutorial to parse json object response with source code download
Case 2 : Parsing a json array response
[ { "username":"jon", "email":"jon@email.com" }, { "username":"smith", "email":"smith@email.com" } ]
Here we have a json array example since its of the form [{...} ,{...}]
Here we can use the above model class(which we used for object parsing) itself. This is because even if it is an array response but the array consists of objects which is same as our before object response. But since its a collection of objects we will need to fetch it as a list from app side i.e, Call<List<JsonResponse>>, see below
Retrofit 2 code
As highlighted below change all Call<JsonResponse> to Call<List<JsonResponse>>
Retrofit retrofit = new Retrofit.Builder() .baseUrl("base_url/") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestInterface request = retrofit.create(RequestInterface.class); Call<List<JsonResponse>> call = request.getJSON(); call.enqueue(new Callback<List<JsonResponse>>() { @Override public void onResponse(Call<List<JsonResponse>> call, Response<List<JsonResponse>> response) { } @Override public void onFailure(Call<List<JsonResponse>> call, Throwable t) { Log.d("Error",t.getMessage()); } });
also change your RequestInterface.java
public interface RequestInterface { @GET("your_endpoint") Call<List<JsonResponse>> getJSON(); }
You may also take a look at this tutorial to parse json array with source code download
Thats it! you can now start parsing similar json structures :)
You may also check the following video that shows how to parse a json response using retrofit 2
Happy Coding!!
Thank you. I had the opposite. Strongly helped
ReplyDeleteglad it helped, always happy to help!
DeleteСпасибо вам. У меня был положения обратное. Сильно выручили
ReplyDeleteSome truly interesting information, well written and broadly user pleasant. Online JSON Formatter
ReplyDeleteThank you so much!
ReplyDeleteThank you so much
ReplyDeleteHello, I follow the same procedure but getting error: "Expected BEGIN_OBJECT but was string"
ReplyDeleteyou will have to make your call be keeping the callback param as string like this -- Callback < String > , also use ScalarsConverterFactory instead of GsonConverterFactory
ReplyDeleteHello, I have an issue if i want a response of particularly one json array value. Can u please help me.
ReplyDeletei mean i want to sent username to server and want user related response back which is in the form of json array
ReplyDelete