Dedicated Server

How to parse json using Retrofit 2, Android







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

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<JsonResponseas 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<JsonResponseto 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!!



10 comments:

  1. Thank you. I had the opposite. Strongly helped

    ReplyDelete
  2. Спасибо вам. У меня был положения обратное. Сильно выручили

    ReplyDelete
  3. Some truly interesting information, well written and broadly user pleasant. Online JSON Formatter

    ReplyDelete
  4. Hello, I follow the same procedure but getting error: "Expected BEGIN_OBJECT but was string"

    ReplyDelete
  5. you will have to make your call be keeping the callback param as string like this -- Callback < String > , also use ScalarsConverterFactory instead of GsonConverterFactory

    ReplyDelete
  6. Hello, I have an issue if i want a response of particularly one json array value. Can u please help me.

    ReplyDelete
  7. i mean i want to sent username to server and want user related response back which is in the form of json array

    ReplyDelete