Removing deserialization of an object containing a single list with gson
I have the following json. I want to deserialize:
{
"locations": [{
"id": 17,
"account_id": 11,
"name": "The Haunted Lexington",
"radius": 100
}]
}
(In this particular case, there is only one Location
, but there can be many).
I deserialize this with Gson with the following code:
Gson gson = new GsonBuilder().create();
LocationList ll = gson.fromJson(jsonString, LocationList.class);
I have the following classes defined:
public class Location {
@SerializedName("id")
private long mId;
@SerializedName("account_id")
private long mAccountId;
@SerializedName("name")
private String mName;
@SerializedName("radius")
private int mRadius;
public long getId() {
return mId;
}
public String getName() {
return mName;
}
}
and
public class LocationList {
@SerializedName("locations")
private List<Location> mLocations;
}
The fact that I have a bunch of these classes "dummy", which contain a single object, which contains a list of other objects (eg UserList
, MessageList
etc.)
I would like the above json to parse so that I can skip the definition of the intermediate class LocationList
, like this:
Gson gson = new GsonBuilder().create();
// Use the same json as above, but skip defining the superfluous "LocationList" class
List<Location> ll = gson.fromJson(jsonString, "locations", ArrayList<Location>.class);
Is there a way I can do this, perhaps by providing a custom deserializer?
source to share
I recently ran into a similar problem and solved it like this:
// Parse the JSON response.
JSONArray jsonArray = new JSONArray(response);
List<Location> locations = new ArrayList<Location>();
/*
* Create a Location object for every JSONObject in the response,
* and add it to the list.
*/
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Location location = new Gson().fromJson(jsonObject.toString(),
Location.class);
locations.add(location);
The approach here is to iterate over all the locations in an array of locations in JSON, fetching them one at a time, and then adding them to the list.
The JSON I worked with had a list as root object, so you probably can't use that one JSONArray jsonArray = new JSONArray(response);
. Something like this might better suit your situation.
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray locationsJsonArray = jsonObject.get("locations");
I haven't tested these last 2 lines, but I think you get the idea.
Hope you can use this to solve your problem.
source to share
I am currently using a simple method to achieve your goal:
private static <T> List<T> getList(final String jsonVal, final String listTag, T t) {
try {
JsonObject jsonObject = (JsonObject)(new JsonParser()).parse(jsonVal); // root JsonObject. i.e. "locations"
JsonArray jsonArray = (JsonArray)jsonObject.get(listTag);
Gson gson = new GsonBuilder().create();
List<T> list = gson.fromJson(jsonArray, new TypeToken<List<T>>() {}.getType());
return list;
} catch (Exception e) {
throw new IllegalArgumentException("Unexpected json structure!", e);
}
}
Using example:
final GsonBuilder gsonBuilder = new GsonBuilder();
final Gson gson = gsonBuilder.create();
String jsonString = "{\"locations\":[{\"id\":17,\"account_id\":11,\"name\":\"The Haunted Lexington\",\"radius\":100}]}";
List<Location> list = getList(jsonString, "locations", new Location());
This method should be used for your orther classes, for example:
List<User> userList = getList(jsonString, "users", new User());
List<Message> messageList = getList(jsonString, "messages", new Message());
source to share