How to write a GSON deserializer for an embedded object with two possible types

I am having trouble deserializing a java object because the field ("information") inside the object can be one of two possible types: either ArrayList or just String.Here - this is what I have done so far:

First create the Base class:

public class Base {
}

Next, create subclasses:

public class GoodInfo extends Base {
    public ArrayList<MyCustomObject> info;
}

public class BadInfo extends Base {
    public String info;
}

So, now I would like to parse my JSON, which is an ArrayList of underlying objects (i.e. an ArrayList of objects, where each object is either an ArrayList or String):

Type listOfBase = new TypeToken<ArrayList<Base>>(){}.getType();
ArrayList<Base> resp=gson.fromJson(jsonText, listOfBase);

I know that for this I have to write my own deserializer. Deserializer is as follows:

private class MyCustomDeserializer implements JsonDeserializer<DateTime> {
    public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
  throws JsonParseException {
        // WHAT DO I DO HERE?
    }
}

, , , , . - , ?

, :

private class MyCustomDeserializer implements JsonDeserializer<DateTime> {
    public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
  throws JsonParseException {
        try {
            GoodInfo goodInfo=SOMEHOW TRY TO DESERIALIZE json INTO A GoodInfo object
            return goodInfo;
        } catch {
            //
        }
        try {
            BadInfo badInfo=SOMEHOW TRY TO DESERIALIZE json INTO A BadInfo object
            return badInfo;
        } catch {
            throw new JsonParseException("Could not deserialize");
        }
    }
}

context.deserialize json, GSON: . , JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext). , Gson .

, ?

+4
2

( ):

... json, ...

context.deserialize(...), .

json info , :

public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    final JsonElement elem = json.getAsJsonObject()
                                 .get("info");
    if (elem.isJsonArray()) {
        return context.deserialize(json, GoodInfo.class);
    }
    return context.deserialize(json, BadInfo.class);
}

JsonDeserializer , . info Object, :

public class Base {
    public Object info;
}

Gson .

+5
class MyCustomDeserializer implements JsonDeserializer<Base>
{
    public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
        try
        {
            return context.deserialize(json, GoodInfo.class);
        }
        catch (JsonParseException e)
        {
            return context.deserialize(json, BadInfo.class);
        }
    }
}

, GoodInfo BadInfo , Base GSON, GoodInfo BadInfo Base.

, toString():

class GoodInfo extends Base
{
    public ArrayList<String> info;

    public String toString()
    {
        return info.toString();
    }
}

class BadInfo extends Base
{
    public String info;

    public String toString()
    {
        return info;
    }
}

:

Type listOfBase = new TypeToken<ArrayList<Base>>(){}.getType();
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Base.class, new MyCustomDeserializer());
Gson gson = gsonBuilder.create();
ArrayList<Base> resp = gson.fromJson("[{\"info\": \"test\"}, {\"info\": [\"test\", \"test\", \"test\"]}]", listOfBase);
System.out.println(resp.size());
for (Object o : resp) System.out.println(o);

:

2 test [test, test, test]

+3

Source: https://habr.com/ru/post/1568686/


All Articles