Question

I get an error trying to deserializing my data structure, which is a list of items, every one of them implements an interface. In addition, one of the fields of the interface is object, and every inheritance treats this Object as different field.

After so many hours spent on this issue, any answer will be appreciated.

This is the error I receive:

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map at flexjson.factories.BeanObjectFactory.instantiate(BeanObjectFactory.java:17) at flexjson.ObjectBinder.bind(ObjectBinder.java:86) at flexjson.ObjectBinder.bindIntoObject(ObjectBinder.java:139) at flexjson.factories.ClassLocatorObjectFactory.instantiate(ClassLocatorObjectFactory.java:38) at flexjson.ObjectBinder.bind(ObjectBinder.java:86) at flexjson.ObjectBinder.bindIntoCollection(ObjectBinder.java:101) at flexjson.factories.ListObjectFactory.instantiate(ListObjectFactory.java:13) at flexjson.ObjectBinder.bind(ObjectBinder.java:86) at flexjson.ObjectBinder.bind(ObjectBinder.java:65) at flexjson.JSONDeserializer.deserialize(JSONDeserializer.java:158) at testSerizlizeDeserializeInterface.entryPointForTestingSerialize.main(entryPointForTestingSerialize.java:34)

I made an example if anyone would like to try and play with it as well...

  1. The interface
  2. The EPersonType
  3. The inheritance
  4. The main class
  5. The output

Thanks!

The interface

    public interface IPerson {
        EPersonType getPersonType();
        String getName();
        void setName(String name);
            int getAge();
        void setAge(int age);
        Object getValue();
            void setValue(Object value);
    }

Its a pretty straightforward interface. The tricky part, as I already mentioned, is that the value represented as an Object, will contain different values based on interface implementation.

EPersonType

public enum EPersonType {
    Father,
    Mother,
}

The inheritance

    public class Father implements IPerson {

    private String name;
    private int age;
    private String value;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    @Override
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public void setValue(Object value) {
        this.value = (String) value;
    }
    @Override
public EPersonType getPersonType() {
    return EPersonType.Father;
}


}

And another instance

public class Mother implements IPerson {
    private String name;
    private int age;
    private boolean value;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    @Override
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public void setValue(Object value) {
        this.value = (boolean) value;
    }
    @Override
public EPersonType getPersonType() {
    return EPersonType.Mother;
}


}

The main class

public class entryPointForTestingSerialize {

    public static void main(String[] args) {
        List<IPerson> family = new ArrayList<IPerson>();

        IPerson father = new Father();
        father.setAge(50);
        father.setName("Oz");
        father.setValue("Hello");

        IPerson mother = new Mother();
        mother.setAge(50);
        mother.setName("Mother");
        mother.setValue(false);

        family.add(father);
        family.add(mother);

        String serialized = new JSONSerializer().deepSerialize(family);

        System.out.println(serialized);

    List<IPerson> deserialized = (List<IPerson>) new flexjson.JSONDeserializer<List<IPerson>>()
            .use("values", new TypeLocator<String>("personType")
                    .add("Mother", Mother.class).add("Father", Father.class))
            .deserialize(serialized);

        System.out.println(deserialized);
    }
}

The output

[{"age":50,"class":"testSerizlizeDeserializeInterface.Father","name":"Oz","personType":"Father","value":"Hello"},{"age":50,"class":"testSerizlizeDeserializeInterface.Mother","name":"Mother","personType":"Mother","value":false}]

Thanks!

Ozrad.

Was it helpful?

Solution

I solved it by changing the infrastructure to a better one, from my perspective. Its name is XStream and it handled everything smoothly and quickly. These lines of code, and it was all done:

    XStream xstream = new XStream(new DomDriver()); // does not require XPP3 library
    String xml = xstream.toXML(family);

and to get the data back:

    List<IPerson> familyAfterSerialize = (List<IPerson>)xstream.fromXML(xml);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top