次の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<Shape> shapes;
// other stuff
}
GSONにShapeHolder
のインスタンスをJSONにシリアル化しても問題ありません。しかし、そのJSONの文字列を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
それで、私は here を見て、自分のShapeInstanceCreator
を実装し始めました:
public class ShapeInstanceCreator implements InstanceCreator<Shape> {
@Override
public Shape createInstance(Type type) {
// TODO: ???
return null;
}
}
しかし、今私は行き詰まっています:Java.lang.reflect.Type
、しかし私は本当にJava.lang.Object
したがって、次のようなコードを記述できます。
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;
}
}
私に何ができる?
@raffianの提案(彼/彼女が投稿したリンク)に従って、私はInterfaceAdapter
exactlyをリンクのように実装しました(私はしませんでした) 何も変更しない)。今、私は次の例外を得ています:
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)
何か案は?
this を見ましたか? InstanceCreatorsを実装するすてきな方法のように見えます。
私もGsonを使用していましたが、シリアル化の問題により FlexJSON に切り替えました。 Flexでは、インスタンス作成者は必要ありません。オブジェクトにJavaBean仕様に基づくすべてのフィールドのゲッター/セッターがあることを確認してください。
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);
FlexJSON は、以下のシリアル化時間のように、jsonの一部としてクラス名を追加することに注意してください。
{
"HTTPStatus": "OK",
"class": "com.XXX.YYY.HTTPViewResponse",
"code": null,
"outputContext": {
"class": "com.XXX.YYY.ZZZ.OutputSuccessContext",
"eligible": true
}
}
したがって、JSONは扱いにくいものになります。しかし、GSONで必要なInstanceCreator
を書く必要はありません。