IAmYourFaja IAmYourFaja - 19 days ago 13
Java Question

GSON and InstanceCreator issue

I have the following POJOs:

public interface Shape {
public double calcArea();
public double calcPerimeter();
}

public class Rectangle implement Shape {
// Various properties of a rectangle
}

public class Circle implements Shape {
// Various properties of a circle
}

public class ShapeHolder {
private List<Shape> shapes;

// other stuff
}


I have no problem getting GSON to serialize an instance of
ShapeHolder
to JSON. But when I try to deserialize a String of that JSON back into a
ShapeHolder
instance, I get errors:

String shapeHolderAsStr = getString();
ShapeHolder holder = gson.fromJson(shapeHodlderAsStr, ShapeHolder.class);


Throws:

Exception in thread "main" java.lang.RuntimeException: Unable to invoke no-args constructor for interface
net.myapp.Shape. Register an InstanceCreator with Gson for this type may fix this problem.
at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
... rest of stack trace ommitted for brevity


So I looked here and started implementing my own
ShapeInstanceCreator
:

public class ShapeInstanceCreator implements InstanceCreator<Shape> {
@Override
public Shape createInstance(Type type) {
// TODO: ???
return null;
}
}


But now I'm stuck: I'm only given a
java.lang.reflect.Type
, but I really need a
java.lang.Object
so I can write code like:

public class ShapeInstanceCreator implements InstanceCreator<Shape> {
@Override
public Shape createInstance(Type type) {
Object obj = convertTypeToObject(type);

if(obj instanceof Rectangle) {
Rectangle r = (Rectangle)obj;
return r;
} else {
Circle c = (Circle)obj;
return c;
}

return null;
}
}


What can I do? Thanks in advance!

UPDATE:

Per @raffian's suggestion (the link he/she posted), I implemented an
InterfaceAdapter
exactly like the one in the link (I didn't change anything). Now I'm getting the following exception:

Exception in thread "main" com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper
at net.myapp.InterfaceAdapter.get(InterfaceAdapter.java:39)
at net.myapp.InterfaceAdapter.deserialize(InterfaceAdapter.java:23)


Any ideas?

Answer

Did you look at this? Looks like a nice clean way to implement InstanceCreators.

I was using Gson too, but switched to FlexJSON due to serialization issues. With Flex, you don't need instance creators, just make sure your objects have getters/setters for all fields based on JavaBean spec, and you're good to go:

 ShapeHolder sh = new ShapeHolder();
 sh.addShape(new Rectangle());
 sh.addShape(new Circle());
 JSONSerializer ser = new JSONSerializer();
 String json = ser.deepSerialize(sh);
 JSONDeserializer<ShapeHolder> der = new JSONDeserializer<ShapeHolder>();
 ShapeHolder sh2 = der.deserialize(json);