Jacob Nelson Jacob Nelson - 1 year ago 79
Java Question

Gson custom deseralizer for one variable in an object

My probelm example:

We have an object type of Apple. Apple has some member variables:

String appleName; // The apples name
String appleBrand; // The apples brand
List<Seed> seeds; // A list of seeds the apple has

And the seed object looks as follows.

String seedName; // The seeds name
long seedSize; // The size of the seed

Now When I get an apple object, an apple could have more than one seed, or it could have one seed, or maybe no seeds!

Example JSON apple with one seed:

"apple" : {
"apple_name" : "Jimmy",
"apple_brand" : "Awesome Brand" ,
"seeds" : {"seed_name":"Loopy" , "seed_size":"14" }

Example JSON apple with two seeds:

"apple" : {
"apple_name" : "Jimmy" ,
"apple_brand" : "Awesome Brand" ,
"seeds" : [
"seed_name" : "Loopy",
"seed_size" : "14"
"seed_name" : "Quake",
"seed_size" : "26"

Now the issue here is the first example is a JSONObject for seeds, the second example is a JSONArray for seeds. Now I know its inconsistent JSON and the easiest way to fix it would be fix the JSON itself, but unfortunately I'm getting the JSON from some one else, so I cant fix it. What would be the easiest way to fix this issue?

Answer Source

You need to register a custom type adapter for the Apple type. In the type adapter, you will add logic to determine if you were given an array or a single object. Using that info, you can create your Apple object.

In adition to the below code, modify your Apple model object so that the seeds field isn't automatically parsed. Change the variable declaration to something like:

private List<Seed> seeds_funkyName;

Here is the code:

GsonBuilder b = new GsonBuilder();
b.registerTypeAdapter(Apple.class, new JsonDeserializer<Apple>() {
    public Apple deserialize(JsonElement arg0, Type arg1,
        JsonDeserializationContext arg2) throws JsonParseException {
        JsonObject appleObj = arg0.getAsJsonObject();
        Gson g = new Gson();
        // Construct an apple (this shouldn't try to parse the seeds stuff
        Apple a = g.fromJson(arg0, Apple.class);
        List<Seed> seeds = null;
        // Check to see if we were given a list or a single seed
        if (appleObj.get("seeds").isJsonArray()) {
            // if it's a list, just parse that from the JSON
            seeds = g.fromJson(appleObj.get("seeds"),
                    new TypeToken<List<Seed>>() {
        } else {
            // otherwise, parse the single seed,
            // and add it to the list
            Seed single = g.fromJson(appleObj.get("seeds"), Seed.class);
            seeds = new ArrayList<Seed>();
        // set the correct seed list
        return a;

For some more info, see the Gson guide.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download