GSON和InstanceCreator问题
我有以下POJO:
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 shapes; // other stuff }
我没有问题让GSON将ShapeHolder的一个实例序列化为JSON。 但是当我尝试将该JSON的String反序列化为ShapeHolder
实例时,我收到错误:
String shapeHolderAsStr = getString(); ShapeHolder holder = gson.fromJson(shapeHodlderAsStr, ShapeHolder.class);
抛出:
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
所以我看了一下并开始实现我自己的ShapeInstanceCreator
:
public class ShapeInstanceCreator implements InstanceCreator { @Override public Shape createInstance(Type type) { // TODO: ??? return null; } }
但现在我卡住了:我只给了一个java.lang.reflect.Type
,但我真的需要一个java.lang.Object
所以我可以编写如下代码:
public class ShapeInstanceCreator implements InstanceCreator { @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; } }
我能做什么? 提前致谢!
更新 :
根据@ raffian的建议(他/她发布的链接),我实现了一个完全类似链接中的InterfaceAdapter
(我没有改变任何东西 )。 现在我收到以下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)
有任何想法吗?
你看看这个吗? 看起来像是一个很好的干净方式来实现InstanceCreators。
我也在使用Gson,但由于序列化问题而切换到FlexJSON 。 使用Flex,您不需要实例创建者,只需确保您的对象具有基于JavaBean规范的所有字段的getter / setter,您就可以了:
ShapeHolder sh = new ShapeHolder(); sh.addShape(new Rectangle()); sh.addShape(new Circle()); JSONSerializer ser = new JSONSerializer(); String json = ser.deepSerialize(sh); JSONDeserializer der = new JSONDeserializer (); ShapeHolder sh2 = der.deserialize(json);
请注意, FlexJSON正在添加类名作为json的一部分,如下面的序列化时间。
{ "HTTPStatus": "OK", "class": "com.XXX.YYY.HTTPViewResponse", "code": null, "outputContext": { "class": "com.XXX.YYY.ZZZ.OutputSuccessContext", "eligible": true } }
所以JSON会有些麻烦; 但是您不需要编写GSON中需要的InstanceCreator。