GSON和InstanceCreator问题 [英] GSON and InstanceCreator issue
问题描述
我有以下POJO:
public interface Shape {
public double calcArea();
public double calcPerimeter();
}
public class Rectangle implements Shape {
//矩形的各种属性
}
public class Circle实现Shape {
//圆的各种属性
}
公共类ShapeHolder {
私人列表<形状>形状;
//其他东西
}
我没有问题让GSON将 ShapeHolder
的实例序列化为JSON。但是,当我尝试将该JSON的字符串反序列化回到 ShapeHolder
实例时,出现错误:
String shapeHolderAsStr = getString();
ShapeHolder holder = gson.fromJson(shapeHodlderAsStr,ShapeHolder.class);
抛出:
线程main中的异常java.lang.RuntimeException:无法为接口
net.myapp.Shape调用无参数构造函数。用Gson注册一个InstanceCreator来解决这个问题。
at com.google.gson.internal.ConstructorConstructor $ 8.construct(ConstructorConstructor.java:167)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ Adapter.read(ReflectiveTypeAdapterFactory.java:162 )
...为了简洁省略了堆栈跟踪的其余部分
所以我看了这里并开始实施我自己的 ShapeInstanceCreator
:
public class ShapeInstanceCreator实现InstanceCreator< Shape> {
@Override
public Shape createInstance(Type type){
// TODO:???
返回null;
}
}
但现在我卡住了:我只是给定一个 java.lang.reflect.Type
,但是我真的需要一个 java.lang.Object
,这样我就可以编写代码如下:
public class ShapeInstanceCreator实现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;
}
返回null;
}
}
我该怎么办?提前感谢!
更新:
Per @ raffian的建议他/她发布了),我实现了一个 InterfaceAdapter
完全,就像链接中的一样(我没有更改任何东西)。现在我收到以下异常:
线程main中的异常com.google.gson.JsonParseException:no'type '会员在net.myapp.InterfaceAdapter.get(InterfaceAdapter.java:39)
处的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< ShapeHolder> der = new JSONDeserializer< ShapeHolder>();
ShapeHolder sh2 = der.deserialize(json);
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?
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);
这篇关于GSON和InstanceCreator问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!