Asked  7 Months ago    Answers:  5   Viewed   47 times

I have a trouble finding a way how to parse JSONArray. It looks like this:

[{"name":"name1","url":"url1"},{"name":"name2","url":"url2"},...]

I know how to parse it if the JSON was written differently (In other words, if I had json object returned instead of an array of objects). But it's all I have and have to go with it.

*EDIT: It is a valid json. I made an iPhone app using this json, now I need to do it for Android and cannot figure it out. There are a lot of examples out there, but they are all JSONObject related. I need something for JSONArray.

Can somebody please give me some hint, or a tutorial or an example?

Much appreciated !

 Answers

81

use the following snippet to parse the JsonArray.

JSONArray jsonarray = new JSONArray(jsonStr);
for (int i = 0; i < jsonarray.length(); i++) {
    JSONObject jsonobject = jsonarray.getJSONObject(i);
    String name = jsonobject.getString("name");
    String url = jsonobject.getString("url");
}

Hope it helps.

Tuesday, June 1, 2021
 
hakre
answered 7 Months ago
42

Just call in the callback a list of Strings and it should do the job...

new Callback<List<String>>().
Saturday, June 19, 2021
 
Eugenie
answered 6 Months ago
56

Here's a comprehensive example on how to use Gson with a list of objects. This should demonstrate exactly how to convert to/from Json, how to reference lists, etc.

Test.java:

import com.google.gson.Gson;
import java.util.List;
import java.util.ArrayList;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;


public class Test {

  public static void main (String[] args) {

    // Initialize a list of type DataObject
    List<DataObject> objList = new ArrayList<DataObject>();
    objList.add(new DataObject(0, "zero"));
    objList.add(new DataObject(1, "one"));
    objList.add(new DataObject(2, "two"));

    // Convert the object to a JSON string
    String json = new Gson().toJson(objList);
    System.out.println(json);

    // Now convert the JSON string back to your java object
    Type type = new TypeToken<List<DataObject>>(){}.getType();
    List<DataObject> inpList = new Gson().fromJson(json, type);
    for (int i=0;i<inpList.size();i++) {
      DataObject x = inpList.get(i);
      System.out.println(x);
    }

  }


  private static class DataObject {
    private int a;
    private String b;

    public DataObject(int a, String b) {
      this.a = a;
      this.b = b;
    }

    public String toString() {
      return "a = " +a+ ", b = " +b;
    }
  }

}

To compile it:

javac -cp "gson-2.1.jar:." Test.java

And finally to run it:

java -cp "gson-2.1.jar:." Test

Note that if you're using Windows, you'll have to switch : with ; in the previous two commands.

After you run it, you should see the following output:

[{"a":0,"b":"zero"},{"a":1,"b":"one"},{"a":2,"b":"two"}]
a = 0, b = zero
a = 1, b = one
a = 2, b = two

Keep in mind that this is only a command line program to demonstrate how it works, but the same principles apply within the Android environment (referencing jar libs, etc.)

Tuesday, June 29, 2021
 
Laimoncijus
answered 6 Months ago
94

This is a JSONArray and not a JSONObject - to make a JSONObject from it, use

JSONObject jsonObject = jsonArray.getJSONObject(0);

this gets the first JSONObject from this JSONArray.

If you have multiple JSONObjects, use this:

JSONObject jsonObject;
for(int n = 0; n < jsonArray.length(); n++)
{
    jsonObject = jsonArray.getJSONObject(n);
}

To get the values:

jsonObject.getString("name");
Monday, October 4, 2021
 
stfn
answered 2 Months ago
74

I think that the philosophy of Gson is to map the Json structure to an objects graph. So in your case I would probably create all the needed java objects to map correctly the json structure. In addition of that, maybe one day you will need some other information of the response, so it will be easier to do the evolution. Something like that (the proper way I think):

class RouteResponse {
    private List<Route> routes;
}
class Route {
    private List<Bound> bounds;
    private String copyrights;
    private List<Leg> legs;
}
class Leg {
    private Distance distance;
    private Duration duration;
    private String endAddress;
    ...
}
class TextValue {
    private String text;
    private String value;
}
class Distance extends TextValue {
}
// And so on

And I would use an ExclusionStrategy to have light objects and to have only the fields I'm interested in. It sounds to me like the proper way to do that.

Now if you really want to retrieve only the list of distances, I'm sure you can do that with a custom TypeAdapter and TypeAdapterFactory.

Something like that (the bad way :-)):

The objects to map the response:

public class RouteResponse {

    private List<Distance> distances;

   // add getters / setters
}

public class Distance {

    private String text;
    private String value;

   // add getters / setters
}

The factory that instantiates our adapter (With a reference to the Gson object, so the adapter can retrieve delegates) :

public class RouteResponseTypeAdapterFactory implements TypeAdapterFactory {

    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if (type.getRawType() == RouteResponse.class) {
            return (TypeAdapter<T>)new RouteResponseTypeAdapter(gson);
        }
        return null;
    }
}

And the type adapter: this implementation will first unmarshall the Json document to a JsonElements tree and then will retrieve the needed JsonObjects to create through the delegate the Distance objects (sorry for the bad code, quickly written).

public class RouteResponseTypeAdapter extends TypeAdapter<RouteResponse> {

    private final TypeAdapter<JsonElement> jsonElementTypeAdapter;
    private final TypeAdapter<Distance> distanceTypeAdapter;

    public RouteResponseTypeAdapter(Gson gson) {
        this.jsonElementTypeAdapter = gson.getAdapter(JsonElement.class);
        this.distanceTypeAdapter = gson.getAdapter(Distance.class);
    }

    @Override
    public void write(JsonWriter out, RouteResponse value) throws IOException {
        throw new UnsupportedOperationException("Not implemented");
    }

    @Override
    public RouteResponse read(JsonReader jsonReader) throws IOException {
        RouteResponse result = new RouteResponse();
        List<Distance> distances = new ArrayList<>();
        result.setDistances(distances);
        if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) {
            JsonObject responseObject = (JsonObject) jsonElementTypeAdapter.read(jsonReader);
            JsonArray routes = responseObject.getAsJsonArray("routes");
            if (routes != null) {
                for (JsonElement element:routes) {
                    JsonObject route = element.getAsJsonObject();
                    JsonArray legs = route.getAsJsonArray("legs");
                    if (legs != null) {
                        for (JsonElement legElement:legs) {
                            JsonObject leg = legElement.getAsJsonObject();
                            JsonElement distanceElement = leg.get("distance");
                            if (distanceElement != null) {
                                distances.add(distanceTypeAdapter.fromJsonTree(distanceElement));
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
}

Finally, you can parse your json document:

    String json = "{ routes: [ ....."; // Json document
    Gson gson = new GsonBuilder().registerTypeAdapterFactory(new RouteResponseTypeAdapterFactory()).create();
    RouteResponse response = gson.fromJson(json, RouteResponse.class);
    //response.getDistances() should contain the distances

Hope it helps.

Sunday, October 17, 2021
 
Marcelo
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share