zovits
zovits

Reputation: 915

Gson cannot deserialize List<Serializable>

I'm trying to deserialize a JSON I got from a server into its original POJO form. I know the original Object (I have the source of the server's code), but it seems I'm missing something.

Here is the minimal code sample I could assemble that illustrates my problem:

package mycompany.mypackage;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;

public class GsonSerializeTest {

    /* main method to illustrate the problem */
    public static void main(String[] args) {
        Serializable[] identifiers= {"ITEM",12345678,"abc.def.ghijkl.mnopqr",87654321};
        EntityUid uid = new GsonSerializeTest().new EntityUid(identifiers);
        Gson converter = new GsonBuilder().registerTypeAdapter(Serializable.class, new GsonSerializeTest().new SerializableInstanceCreator()).create();
        String json = converter.toJson(uid);
        System.out.println("Converted to string: " + json);
        EntityUid uid2 = converter.fromJson(json, EntityUid.class); // ERROR
        System.out.println("Converted back to object: " + uid2);
    }

    /* the POJO that gets serialized and fails while deserializing */
    public class EntityUid implements Serializable {
        private final List<Serializable> identifier = new ArrayList<Serializable>();

        public EntityUid(final Serializable... identifier) {
            for (Serializable partialIdentifier : identifier) {
                this.identifier.add(partialIdentifier);
            }
        }
    }

    /* Class for generating Serializable instances */
    public class SerializableInstanceCreator implements InstanceCreator<Serializable> {
        public Serializable createInstance(Type arg0) {
            return new String();
        }
    }
}

This prepares the EntityUid object, serializes it (just as the server does) into this:

Converted to string: {"identifier":["ITEM",12345678,"abc.def.ghijkl.mnopqr",87654321]}

and then tries to deserialize it into the original Object, but fails with the following:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 17
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.Gson.fromJson(Gson.java:803)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
    at mycompany.mypackage.GsonSerializeTest.main(GsonSerializeTest.java:19)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 17
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165)
    ... 10 more

Could somebody please provide me a pointer on what might I be missing? Thanks a lot in advance!

Upvotes: 0

Views: 2004

Answers (2)

krishnakumarp
krishnakumarp

Reputation: 9295

Please read Serializing and Deserializing Collection with Objects of Arbitrary Types.

This below code will work though.

import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class GsonSerializeTest {

    /* main method to illustrate the problem */
    public static void main(String[] args) {
        Object[] identifiers= {12345678,"ITEM","abc.def.ghijkl.mnopqr",87654321};
        EntityUid uid = new EntityUid(identifiers);
        Gson converter = new GsonBuilder().create();
        String json = converter.toJson(uid);
        System.out.println("Converted to string: " + json);
        EntityUid uid2 = converter.fromJson(json, EntityUid.class); // ERROR
        System.out.println("Converted back to object: " + uid2);
    }

    /* the POJO that gets serialized and fails while deserializing */
    public static class EntityUid  {
        private final List<Object> identifier = new ArrayList<Object>();

        public EntityUid(final Object... identifier) {
            for (Object partialIdentifier : identifier) {
                this.identifier.add(partialIdentifier);
            }
        }

        @Override
        public String toString() {
            return "EntityUid [identifier=" + identifier + "]";
        }


    }
}

Upvotes: 2

user149621
user149621

Reputation: 529

Go through the below post it will help you.

Android JSon error "Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2".

Collections Limitations:

Can serialize collection of arbitrary objects but can not deserialize from it Because there is no way for the user to indicate the type of the resulting object While deserializing, Collection must be of a specific generic type All of this makes sense, and is rarely a problem when following good Java coding practices

Upvotes: 0

Related Questions