2012-12-10 8 views
7

Jerseyを使用してRESTサービスを作成しています。@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)が応答が返されたときに動作しない

@GET 
@Produces(MediaType.APPLICATION_JSON) 
@Path("promotions/") 
public List<Promotion> getClosestPromotions() { 
List<Promotion> promotions = getPromotions(); //here I get some objects 

return promotions; 
} 

は、私が「@class」フィールドのでJSON文字列を取得します:私は、オブジェクトのリストを返すとき、それに

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 

ありがとう:私は、注釈を持つ抽象クラスの推進を持っていますそのリストのすべてのオブジェクト。

@GET 
@Produces(MediaType.APPLICATION_JSON) 
@Path("promotions/") 
public Response getClosestPromotions() { 
List<Promotion> promotions = getPromotions(); //here I get some objects 

return Response.ok().entity(promotions).build(); 
} 

私はほとんど同じリストを取得しますが、追加の「@class」フィールドなしだ:しかし、問題は、私は応答を返す場合ということです。 これはなぜですか、また、レスポンスでリストを返す "@class"フィールドを持つリストを取得するにはどうすればよいですか? そして、驚くべきことに、エンティティとして指定された1つのPromotionオブジェクトを持つResponseを返すときに動作し、その "@class"フィールドを取得します。

+1

私はまだなく、答えのための十分なを持っていません。エンティティメソッドはObjectを受け取ります。基礎となるコードは、おそらく実行時にタイプ情報を回復するためにタイプを検査します。残念なことに、これはListとしてList ではありません。それはジェネリック型情報なしでそれをリストとして書くので、あなたはクラスフィールドを失います。メンバ変数としてリストを持つオブジェクトを書くことはおそらく動作しますが、私は何かクリーナーを思いついています。 –

答えて

5

たぶん、あなたは試してみたい:サブタイプのアノテーションを追加する

GenericEntity<Collection<Promotion>> genericEntity = 
      new GenericEntity<Collection<Promotion>>(promotions){}; 
return Response.ok().entity(genericEntity).build(); 
+1

ありがとう!私はついにそれを働かせました! – krajol

+1

これはとてもうまく動作するシンプルなソリューションです。共有していただきありがとうございます!唯一の欠点は、常にこのようにコレクションをラップすることを覚えなければならないことです。 –

2

てみ、ここで私が使用しています例です。これは、すべての操作可能なサブタイプを指定することによって、問題を解決する可能性があります。申し訳ありません、あなたの正確な例をテストしませんでした。

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value=MetricCollection.class), 
    @JsonSubTypes.Type(value=Column.class), 
    @JsonSubTypes.Type(value=IntegerColumn.class), 
    @JsonSubTypes.Type(value=DoubleColumn.class), 
    @JsonSubTypes.Type(value=StringColumn.class) 
}) 
public interface IMetricCollection<T extends IMetric> { 
... 
} 
0

あなたのクラスを生成するためにJAXBを使用した場合、あなたは確かにリストを解析するために、異なる種類の@XmlElementsのようなものを持つことができます。

Jersey/Jacksonで同じJAXBクラスを使用している場合は、@JsonTypeInfoと@JsonSubTypesを追加してオブジェクトのリスト/配列の名前を書式設定する方法を説明して、クラスのメタデータを拡張できます。

@JsonTypeInfoは追加する型を記述しますが、@JsonSubTypesは囲まれたコレクションのオプションを示します。たとえば、以下の例に示すように、出力のプロパティを定義するAs.PROPERTYでは、他の2つの型に加えて、型自体( "Form")を含む異なる型の要素を持つことができるエンティティのリスト "フィールド "と"テーブル "。

public class Form { 

    @XmlElements({ 
    @XmlElement(name = "field", type = Field.class), 
    @XmlElement(name = "form", type = Form.class), 
    @XmlElement(name = "table", type = Table.class) 
    }) 
    @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "obj") 
    @JsonSubTypes({ 
    @JsonSubTypes.Type(value = Field.class), 
    @JsonSubTypes.Type(value = Form.class), 
    @JsonSubTypes.Type(value = Table.class) 
    }) 
    @Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2013-11-11T02:08:36-08:00", comments = "JAXB RI v2.2.4-2") 
    @JsonProperty("entities") 
    protected List<Object> fieldOrFormOrTable; 

追加のメタデータとジャージーのジャクソン・デフォルト・シリアライザを使用して、オブジェクトの直列化は、次のようになります...

 "entities": [ 
        { 
        "obj": "Table", 
        "row": { 
         "id": 1, 
         "fields": [ 
          { 
           "id": "DEBUGARY", 
           "type": "Text", 
           "kind": "user" 
          } 
         ] 
        }, 
        "id": "DBGARRAY" 
       }, 
       { 
        "obj": "field", 
        "id": "IDBG", 
        "type": "Text", 
        "kind": "user" 
       }, 
     ..., ..., ...] 
関連する問題