2013-12-07 9 views
8

は、私は次のPOJOを持っている:GSONとInstanceCreator問題

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はJSONにShapeHolderのインスタンスをシリアル化するために取得する必要がありません。しかし、私は戻ってShapeHolderインスタンスにそのJSONの文字列を逆シリアル化しようとすると、私はエラーを取得:

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; 
    } 
} 

しかし、今、私はこだわっている:私はCA私はjava.lang.reflect.Typeを与えられたんだけど、私は本当にjava.lang.Objectを必要としますn書き込みコード:

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; 
    } 
} 

どうすればよいですか?前もって感謝します!

UPDATE:@のraffianの提案(彼/彼女は掲載リンク)毎の

、私は正確にリンク内の1つの(私はを変更していない)のようなInterfaceAdapterを実施しました。今私は次の例外を得ています:

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) 

アイデアはありますか?

+0

これを確認してください:http://stackoverflow.com/a/19600090/1360888、インターフェイスの代わりに基本クラスがありますが、それはあなたの問題のようです。 – giampaolo

答えて

4

thisを見ましたか? InstanceCreatorsを実装するうまいきれいな方法のようです。

Gsonも使用していましたが、シリアル化の問題によりFlexJSONに切り替えました。

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); 
+0

ありがとう@raffian(+1) - 投稿したリンクの例のように、 'InterfaceAdapter'を作成しました。私は 'GsonBuilder'を使って型アダプタとして登録しました(もう例のように)。今私は新しいエラーが発生しています(私の更新された質問を参照してください)。何が起こっているのかについてのアイデアは何ですか?再度、感謝します! – IAmYourFaja

+0

私は謝罪しません、これが私がフレックスに切り替えた理由です。 :-) Gsonを使用するように強制する制約はありますか? – raffian

+0

遅れて申し訳ありませんが、私は就寝してFlexJSONに旋風を与えました。どのような治療!次のようなことを想像してみてください。あなたは間違いなく私を変換しました - ありがとう! – IAmYourFaja

0

NOTE FlexJSONことは、クラス名を追加することです:Flexで、あなたは自分のオブジェクトがJavaBeanの仕様に基づいて、すべてのフィールドのgetter/setterを持っていることを確認し、あなたが行ってもいいです、インスタンスの作成者を必要としません次のようなjsonの一部として、時間をシリアライズします。

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

JSONは一部になります。 GSONで必要とされる書き込みInstanceCreatorは必要ありません。