Problem with GSON and Creative instance

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 a ShapeHolder instance in JSON. But when I try to deserialize the string of this JSON back to the 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 was only given java.lang.reflect.Type , but I really need java.lang.Object so I can write the code:

 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?

Refresh

As suggested by @raffian (the link that he / she posted), I implemented the InterfaceAdapter just like in the link (I did not change anything). Now I get 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?

+10
java reflection gson type-safety deserialization
source share
2 answers

Have you looked at this ? Looks like a nice clean way to implement InstanceCreators.

I used 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 / seters for all fields based on the JavaBean specification, 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); 
+6
source share

NOTE that FlexJSON adds the class name as part of json, as shown below.

 { "HTTPStatus": "OK", "class": "com.XXX.YYY.HTTPViewResponse", "code": null, "outputContext": { "class": "com.XXX.YYY.ZZZ.OutputSuccessContext", "eligible": true } } 

So, JSON will be a bit; but you do not need to write the InstanceCreator , which is required in GSON.

0
source share

All Articles