User
User

Reputation: 732

How to parse a JSON object containing JSON array through Gson?

I am creating an Android app, where I am getting some response in the form of JSON from web.

That JSON file's structure is like this:

{"result": "someresult", "array": [{object1},{object2}]}

Currently I am using the gson.fromJson() method to parse this JSON, but the problem is that array is a JSONArray and its throwing exception that JSONObject is expected. For result and array I am using @SerializedName annotations. How this kind of JSON can be parsed using Gson? Any suggestion will be appreciated.

Here is code:

public class ResultClass {

    @SerializedName("result")
    public String result;

    @SerializedName("array")
    public JSONArray array;

    public static ResultClass getresultFromJSON(String json) {
        try {
            ResultClass resultclass = new Gson().fromJson(json, ResultClass.class);
            return resultclass ;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

Upvotes: 1

Views: 4426

Answers (4)

Lyubomyr Shaydariv
Lyubomyr Shaydariv

Reputation: 21125

Typo... You're getting exception because your Gson instance is not instructed on how to deal with JSONArray (I believe, it's fully-qualified name is org.json.JSONArray), whilst the Gson equivalent is com.google.gson.JsonArray. So the following mapping won't fail:

@SerializedName("array")
public JsonArray array;

Note that you've burned on mixing two different libraries twice, and now while describing the exception you're getting: Gson does not report a JSONObject or whatever like that (it merely does not have any clue on that type), but it reports the BEGIN_OBJECT token (an internal representation of {) type since JSON objects are default for unknown non-primitive types except primitives and arrays.

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 33 path $.array
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
    at com.google.gson.Gson.fromJson(Gson.java:887)
    at com.google.gson.Gson.fromJson(Gson.java:852)
    at com.google.gson.Gson.fromJson(Gson.java:801)
    at com.google.gson.Gson.fromJson(Gson.java:773)
    ...
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 33 path $.array
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
    ... 12 more

Also consider not using JsonArray with your application data classes like that one you're trying to parse (see the RSCh's suggestion). Having JSON-related stuff in those classes usually marks a code smell: some fields are "true Java", some fields are "JSON only". For example, you can define another nested object mapping class and just tell Gson it must be a JSON array in your enclosing class ResultClass, say something like:

@SerializedName("array")
public List<YourElementClass> array;

or

@SerializedName("array")
public YourElementClass[] array;

A typo can affect much.

Upvotes: 1

Moktahid Al Faisal
Moktahid Al Faisal

Reputation: 910

hi if your json looks like this

{"status": "success",
"data": [
  {
    "trip_id": "5",
    "ride_id": "5",
    "start_location": "8 Rd No 14, Dhaka 1209, Bangladesh",
    "end_location": "Uttara Dhaka, Dhaka Division, Bangladesh",
    "date": "2017-03-14 17:36 PM",
    "time_from": "1489491394079.5322 ",
    "time_to": "1489493194079.5322 ",
    "status": 5,
    "trip_earn": "",
    "currency": "CAD"

  },
{
        "trip_id": "5",
        "ride_id": "5",
        "start_location": "8 Rd No 14, Dhaka 1209, Bangladesh",
        "end_location": "Uttara Dhaka, Dhaka Division, Bangladesh",
        "date": "2017-03-14 17:36 PM",
        "time_from": "1489491394079.5322 ",
        "time_to": "1489493194079.5322 ",
        "status": 5,
        "trip_earn": "",
        "currency": "CAD"

      }
]
}

then your write a class like that for parsign the data

public class Example {

@SerializedName("status")
@Expose
private String status;
@SerializedName("data")
@Expose
private List<Datum> data = null;

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public List<Datum> getData() {
return data;
}

public void setData(List<Datum> data) {
this.data = data;
}

}

and

public class Datum {

@SerializedName("trip_id")
@Expose
private String tripId;
@SerializedName("ride_id")
@Expose
private String rideId;
@SerializedName("start_location")
@Expose
private String startLocation;
@SerializedName("end_location")
@Expose
private String endLocation;
@SerializedName("date")
@Expose
private String date;
@SerializedName("time_from")
@Expose
private String timeFrom;
@SerializedName("time_to")
@Expose
private String timeTo;
@SerializedName("status")
@Expose
private Integer status;
@SerializedName("trip_earn")
@Expose
private String tripEarn;
@SerializedName("currency")
@Expose
private String currency;

public String getTripId() {
return tripId;
}

public void setTripId(String tripId) {
this.tripId = tripId;
}

public String getRideId() {
return rideId;
}

public void setRideId(String rideId) {
this.rideId = rideId;
}

public String getStartLocation() {
return startLocation;
}

public void setStartLocation(String startLocation) {
this.startLocation = startLocation;
}

public String getEndLocation() {
return endLocation;
}

public void setEndLocation(String endLocation) {
this.endLocation = endLocation;
}

public String getDate() {
return date;
}

public void setDate(String date) {
this.date = date;
}

public String getTimeFrom() {
return timeFrom;
}

public void setTimeFrom(String timeFrom) {
this.timeFrom = timeFrom;
}

public String getTimeTo() {
return timeTo;
}

public void setTimeTo(String timeTo) {
this.timeTo = timeTo;
}

public Integer getStatus() {
return status;
}

public void setStatus(Integer status) {
this.status = status;
}

public String getTripEarn() {
return tripEarn;
}

public void setTripEarn(String tripEarn) {
this.tripEarn = tripEarn;
}

public String getCurrency() {
return currency;
}

public void setCurrency(String currency) {
this.currency = currency;
}

}

use like

Gson gson = new Gson();
String jsonInString = "{\"userId\":\"1\",\"userName\":\"chayon\"}";
Example user= gson.fromJson(jsonInString, Example.class);
user.getdata().get(position)

Upvotes: 3

RSCh
RSCh

Reputation: 169

Just create class with structure:

class ResultClass {
 String result;
 ArrayData[] array;
}

class ArrayData {
  String field1;
  String field2;
}

After that just use fromJson method:

Gson gson = new GsonBuilder().create();
ResultClass resultClass = gson.fromJson(jsonString, ResultClass.class)

Upvotes: 1

AndiGeeky
AndiGeeky

Reputation: 11464

Create a Response POJO classes using jsonschema2pojo.

Add GSON dependency in your build.gradle

dependencies {
  compile 'com.google.code.gson:gson:2.8.0'
}

Convert your json to specific pojo class as below:

Gson gson = new GsonBuilder().create();
        Response response = gson.fromJson(response, Response.class);

Thanks!

Upvotes: 1

Related Questions