Dedicated Server
Showing posts with label begin_object. Show all posts
Showing posts with label begin_object. Show all posts

Parse a json array inside another json object in android with free source code download




We will be using retrofit,gson for parsing, so go to your app level build.gradle and add the following as dependencies

implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
please add the latest dependency versions for retrofit, converter-gson

Hi, in this tutorial, we will parse the below json. Check this json here >> https://navneet7k.github.io/sample_object_array.json

Here you can see that the cars_array is wrapped inside another json object, so we will need two model/pojo classes


1) Automatic model class/pojo class generation using http://www.jsonschema2pojo.org/


You can make use of jsonschema2pojo to covert json to java object online. This is a really effective tool which even supports various annotation types like jackson, gson, moshi etc.
Specify Target language as Java, Source Type as JSON and annotation style as Gson
  • Now click preview and copy the generated java files
Now copy the contents of the class and add it in android studio project

Now rename the generated classes like shown below and add it inside your android studio project

SampleResponse.java

public class SampleResponse {
    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("type")
    @Expose
    private String type;
    @SerializedName("cars_array")
    @Expose
    private List<CarsArray> carsArray = null;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public List<CarsArray> getCarsArray() {
        return carsArray;
    }

    public void setCarsArray(List<CarsArray> carsArray) {
        this.carsArray = carsArray;
    }

}


CarsArray.java

public class CarsArray {
    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("desc")
    @Expose
    private String desc;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}


MainActivity.java

private void parseJson() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://navneet7k.github.io/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<SampleResponse> call1=request.getJson();
        call1.enqueue(new Callback<SampleResponse>() {
            @Override
            public void onResponse(Call<SampleResponse> call, Response<SampleResponse> response) {
                Toast.makeText(MainActivity.this,"Success! response for first item >> \n car :" +response.body().getCarsArray().get(0).getName()+"\ndesc :"+response.body().getCarsArray().get(0).getDesc(),Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<SampleResponse> call, Throwable t) {
                Toast.makeText(MainActivity.this,"Failure",Toast.LENGTH_SHORT).show();
            }

        });
    }

RequestInterface.java

interface RequestInterface {
    @GET("sample_object_array.json")
    Call<SampleResponse> getJson();
}


Download free source code

Parse json object in android with free source code download




We will be using retrofit,gson for parsing, so go to your app level build.gradle and add the following as dependencies

implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
please add the latest dependency versions for retrofit, converter-gson

Hi, we will be parsing the below json in this tutorial. Check this json here >> https://navneet7k.github.io/sample_object.json

Clearly, the json is of the form {..} and we can parse it as an object from android
Now inorder to generate model class/pojo class for above json, you may either create it automatically using http://www.jsonschema2pojo.org/ or generate it manually

1) Automatic model class/pojo class generation using http://www.jsonschema2pojo.org/

You can make use of jsonschema2pojo to covert json to java object online. This is a really effective tool which even supports various annotation types like jackson, gson, moshi etc.
Specify Target language as Java, Source Type as JSON and annotation style as Gson
  • Now click preview and copy the generated java files
Now copy the contents of the class and add it in android studio project

Now copy the above generated contents into SampleJson.java as shown below

SampleJson.java

public class SampleJson {
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("description")
    @Expose
    private String description;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("id")
    @Expose
    private String id;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}


MainActivity.java

private void parseJson() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://navneet7k.github.io/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<SampleJson> call1=request.getJson();
        call1.enqueue(new Callback<SampleJson>() {
            @Override
            public void onResponse(Call<SampleJson> call, Response<SampleJson> response) {
                Toast.makeText(MainActivity.this,"Success!",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<SampleJson> call, Throwable t) {
                Toast.makeText(MainActivity.this,"Failure",Toast.LENGTH_SHORT).show();
            }

        });
    }

RequestInterface.java

interface RequestInterface {
    @GET("sample_object.json")
    Call<SampleJson> getJson();
}


Download free source code

Parse json array in android with free source code download



We will be using retrofit,gson for parsing, so go to your app level build.gradle and add the following as dependencies

implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
please add the latest dependency versions for retrofit, converter-gson

Hi, in this tutorial we are about to parse the below json array. Check this json array >> https://navneet7k.github.io/sample_array.json

Clearly, the json is of the form [{},{}..] . It is a json array, hence we can parse it as a list from android
Now inorder to generate model class/pojo class for above json, you may either create it automatically using http://www.jsonschema2pojo.org/ or generate it manually

1) Automatic model class/pojo class generation using http://www.jsonschema2pojo.org/
Specify Target language as Java, Source Type as JSON and annotation style as Gson
  • Now click preview and copy the generated java files
Now copy the contents of the class and add it in android studio project
Now in the android studio project, create a new java file Cars.java and add the above generated code inside it like shown below

Cars.java

public class Cars {
    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("desc")
    @Expose
    private String desc;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}


Since the json is an array, we can parse it as a list like this <List<Cars>> from android. So add the below code in your MainActivity.java file

MainActivity.java

private void parseJson() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://navneet7k.github.io/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<List<Cars>> call1=request.getJson();
        call1.enqueue(new Callback<List<Cars>>() {
            @Override
            public void onResponse(Call<List<Cars>> call, Response<List<Cars>> response) {
                Toast.makeText(MainActivity.this,"Success!",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<List<Cars>> call, Throwable t) {
                Toast.makeText(MainActivity.this,"Failure",Toast.LENGTH_SHORT).show();
            }

        });
    }

RequestInterface.java

interface RequestInterface {
    @GET("sample_array.json")
    Call<List<Cars>> getJson();
}


Download free source code

You may also check this tutorial to parse a json array into recyclerview


How to fix "Expected a string but was BEGIN_OBJECT" in GSON

You might have come across a gson exception that says  "Expected a string but was BEGIN_OBJECT". This means that you are parsing the response as if it were a string, but actually it is a json object.

I would recommend you to check how to parse json in android if you have no prior knowledge in parsing json

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'

Suppose your response is a json object, something like the following

{ 
"username":"jon",
"email":"jon@email.com", 
"user_array": [
 { 
 "user_address":"jon",
 "user_location":"jon@email.com"
 }, {..},
 .
 . 
 ]
}

You will receive the error Expected a string but was BEGIN_OBJECT if you try to parse it like this
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("base_url")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

RequestInterface request = retrofit.create(RequestInterface.class);
Call<String> call=request.getJson();
call.enqueue(new Callback<String>() {
    @Override    
    public void onResponse(Call<String> call, Response<String> response) {
        progressDialog.dismiss();
        String s= String.valueOf(response.get("username"));
        JsonArray user_array= response.getAsJsonArray("user_array");
        Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show();
    }

    @Override    
    public void onFailure(Call<String> call, Throwable t) {
        progressDialog.dismiss();
        Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show();
    }
});

GSON will throw the above mentioned error because you have used Call<Stringinstead of using Call<JsonObject> or  using a pojo class

Solution 1 : by using JsonObject:


Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("base_url")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

RequestInterface request = retrofit.create(RequestInterface.class);
Call<JsonObject> call=request.getJson();
call.enqueue(new Callback<JsonObject>() {
    @Override    
    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
        progressDialog.dismiss();
        String s= String.valueOf(response.get("username"));
        JsonArray user_array= response.getAsJsonArray("user_array");
        Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show();
    }

    @Override    
    public void onFailure(Call<JsonObject> call, Throwable t) {
        progressDialog.dismiss();
        Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show();
    }
});

You can see that here we are expecting a JsonObject as response parameter instead of String. Now we can parse the response correctly as we are expecting the same format mentioned in the response. Also dont forget to change the response param in interface to Call<JsonObject> as shown below

RequestInterface.java
public interface RequestInterface {

@GET("api_endpoint")
Call<JsonObject> getJson();

}


Solution 2 : by using POJO class

First create a pojo class like this

Example.java
public class Example {

@SerializedName("username")
@Expose
private String username;
@SerializedName("email")
@Expose
private String email;
@SerializedName("user_array")
@Expose
private List<UserArray> userArray = null;

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;
}

public List<UserArray> getUserArray() {
return userArray;
}

public void setUserArray(List<UserArray> userArray) {
this.userArray = userArray;
}

}

Then use it inside your retrofit call like this

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("base_url")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

RequestInterface request = retrofit.create(RequestInterface.class);
Call<Example> call=request.getJson();
call.enqueue(new Callback<Example>() {
    @Override    
    public void onResponse(Call<Example> call, Response<Example> response) {
        progressDialog.dismiss();
        String user_name= response.getUsername();
        user_array= new ArrayList<>(response.getUserArray());
        Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show();
    }

    @Override    
    public void onFailure(Call<Example> call, Throwable t) {
        progressDialog.dismiss();
        Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show();
    }
});

RequestInterface.java
public interface RequestInterface {
@GET("api_endpoint")
Call<Example> getJson();
}

You can use Call<String> as response param only if your response is not enclosed in curly brackets. In this case the response will be a plain text

How to fix "expected begin_array but was begin_object" in Retrofit ?


Before we begin, keep this in mind

begin_array means the json response is an array which will look something like this [{},{},..]
begin_object means the json response is an object which will look something like this {....}

gson is one cool library that will provide us with cool tips in the form of errors while handling json responses. One such tip is "expected begin_array but was begin_object". These tips/errors are quite self explanatory, we can now look deeper into these errors.

While handling responses using retrofit, we often tend to come across an error "expected begin_array but was begin_object", which is thrown by gson. Obviously this means that we are trying to parse the response as if it is a json array response but when actually it is a json object response. But still we come across these errors a lot of time. We will be looking in detail about such situations in this post.


First add the following 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'

PARSING JSON OBJECT RESPONSES : 

  • json object  response is of the form {....}.  The json object may also contain a json array like the below example where the json object contains a json array named user_array.
{ 
"username":"jon",
"email":"jon@email.com", 
"user_array": [
 { 
 "user_address":"jon",
 "user_location":"jon@email.com"
 }, {..},
 .
 . 
 ]
}


In order to parse the above json object you can either use the JsonObject from gson or create pojo classes


1. Parsing using JsonObject  from gson



Retrofit retrofit = new Retrofit.Builder() .baseUrl("base_url") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestInterface request = retrofit.create(RequestInterface.class); Call<JsonObject> call=request.getJson(); call.enqueue(new Callback<JsonObject>() { @Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { progressDialog.dismiss(); String s= String.valueOf(response.get("username")); JsonArray user_array= response.getAsJsonArray("user_array"); Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<JsonObject> call, Throwable t) { progressDialog.dismiss(); Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show(); } });
RequestInterface.java
public interface RequestInterface { @GET("api_endpoint") Call<JsonObject> getJson(); }

2. Parsing using POJO  class

You can automatically generate the pojo classes by pasting your json response structure in http://www.jsonschema2pojo.org/ .

FYI : after pasting the response structure in http://www.jsonschema2pojo.org/ ,  set the source type to JSON and Annotation style to Gson , now click preview button and you can see generated pojo class/classes

For the above case you will need to generate two classes like below

Example.java

public class Example {

@SerializedName("username")
@Expose
private String username;
@SerializedName("email")
@Expose
private String email;
@SerializedName("user_array")
@Expose
private List<UserArray> userArray = null;

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;
}

public List<UserArray> getUserArray() {
return userArray;
}

public void setUserArray(List<UserArray> userArray) {
this.userArray = userArray;
}

}

UserArray.java

public class UserArray {

@SerializedName("user_address")
@Expose
private String userAddress;
@SerializedName("user_location")
@Expose
private String userLocation;

public String getUserAddress() {
return userAddress;
}

public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}

public String getUserLocation() {
return userLocation;
}

public void setUserLocation(String userLocation) {
this.userLocation = userLocation;
}

}

In the above  pojo classes, we have used @SerializedName annotation which will help us to map the class variables to respective keys in the response json. For example, in UserArray.java, the string variable userAddress is correctly mapped to user_address by using the @SerializedName annotation like this

@SerializedName("user_address")
@Expose
private String userAddress;


The Example.java is for parsing the outer json object whereas UserArray.java is for parsing the inner json object which should be parsed as a list(since there is a list of objects in user_array)


Now the retrofit call should be made like the following

ArrayList<RouteStop> user_array;
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("base_url")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

RequestInterface request = retrofit.create(RequestInterface.class);
Call<Example> call=request.getJson();
call.enqueue(new Callback<Example>() {
    @Override    
    public void onResponse(Call<Example> call, Response<Example> response) {
        progressDialog.dismiss();
        String user_name= response.getUsername();
        user_array= new ArrayList<>(response.getUserArray());
        Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show();
    }

    @Override    
    public void onFailure(Call<Example> call, Throwable t) {
        progressDialog.dismiss();
        Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show();
    }
});

RequestInterface.java
public interface RequestInterface {
@GET("api_endpoint")
Call<Example> getJson();
}

The error "expected begin_array but was begin_object" occurs  if you are trying to parse the above response using Call<List<Example>> call=request.getJson(); because by using <List<Example>> we are clearly making an array request but we need to make an object request since response is of the form {..}

Similarly we get the error "expected begin_object but was begin_array when we are trying to make an object request were the response is of the form [{},{},..], which is a json array example. In such case we should make the call like Call<List<Example>>

Please check this tutorial to parse json array and display it in a recyclerview. Also free source code download is avalaible.

You may also check similar issues in StackOverflow





You may also check the following video that shows how to parse a json response using retrofit 2