GSON ignore elements with wrong type

Define your model like this:

public class ApiResult {

    private String error;
    private String message;
    private String resultCode;
    private MyResultObject resultObj;
}

Then, create a TypeAdapterFactory for MyResultObject:

public class MyResultObjectAdapterFactory implements TypeAdapterFactory {

    @Override
    @SuppressWarnings("unchecked")
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if (type.getRawType()!= MyResultObject.class) return null;

        TypeAdapter<MyResultObject> defaultAdapter = (TypeAdapter<MyResultObject>) gson.getDelegateAdapter(this, type);
        return (TypeAdapter<T>) new MyResultObjectAdapter(defaultAdapter);
    }

    public class MyResultObjectAdapter extends TypeAdapter<MyResultObject> {

        protected TypeAdapter<MyResultObject> defaultAdapter;


        public MyResultObjectAdapter(TypeAdapter<MyResultObject> defaultAdapter) {
            this.defaultAdapter = defaultAdapter;
        }

        @Override
        public void write(JsonWriter out, MyResultObject value) throws IOException {
            defaultAdapter.write(out, value);
        }

        @Override
        public MyResultObject read(JsonReader in) throws IOException {
            /* 
            This is the critical part. So if the value is a string,
            Skip it (no exception) and return null.
            */
            if (in.peek() == JsonToken.STRING) {
                in.skipValue();
                return null;
            }
            return defaultAdapter.read(in);
        }
    }
}

Finally, register MyResultObjectAdapterFactory for Gson:

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(new MyResultObjectAdapterFactory())
    .create();

Now, when deserializing an ApiResult json with that Gson object, resultObj will be set null if it is a string.

I Hope this solves your problem =)


I've had a similar problem and came up with the following solution in the end:

In stead of trying to parse your element into a String or Array, try storing the data to a simple java.lang.Object

This prevents the parsing from crashing or throwing an exception.

eg. with GSON annotations the property of your model would look like this:

@SerializedName("resultObj")
@Expose
private java.lang.Object resultObj;

Next, when accessing your data at runtime, you can check if your resultObj property is an instance of String or not.

if(apiResultObject instanceof String ){
    //Cast to string and do stuff

} else{
    //Cast to array and do stuff

}

Original post: https://stackoverflow.com/a/34178082/3708094