2016-02-17 40 views
1

嘗試了幾個變體後,我被困在試圖讓我的Spring HATEOAS控制器做多態性。與Spring Hateoas的多態性

我的第一個變體是將資源實現爲Resource的實例,我的對象爲content。基類的定義如下:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type") 
@JsonSubTypes({ @Type(value = Cat.class, name = "Cat"), @Type(value = Dog.class, name = "Dog") }) 
@JsonRootName("Animal") 
public abstract class Animal 
{ 
    : 
    : 
} 

時,取單個實例或頁面,下面拋出異常:

Could not write content: Unwrapped property requires use of type information: can not serialize without disabling `SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS` 

完整的攝製,請訪問:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos/spring/hateoas/polymorphism/repro1

我理解是這個錯誤是由ResourcegetContent方法上的@JsonUnwrapped註釋造成的。 PagedResources顯然使用了類似的方法。

我的第二次嘗試是讓我的類繼承ResourceSupport,以規避@JsonUnwrapped問題。基類現在看起來像這樣:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type") 
@JsonSubTypes({ @Type(value = Cat2.class, name = "Cat2"), @Type(value = Dog2.class, name = "Dog2") }) 
@JsonRootName("Animal2") 
public abstract class Animal2 extends ResourceSupport 
{ 
    : 
    : 
} 

這部分工作。一個單一的資源現在連載正確(注意@type屬性):

{ 
    "@type":"Dog2", 
    "name":"nameofdog", 
    "barkVolume":1.0, 
    "_links":{ 
     "self":{ 
     "href":"http://localhost:8082/animals2/nameofdog" 
     } 
    } 
} 

但是,頁面不具有@type屬性:

{ 
    "_embedded":{ 
     "Animal2s":[ 
     { 
      "name":"nameofdog", 
      "barkVolume":1.0, 
      "_links":{ 
       "self":{ 
        "href":"http://localhost:8082/animals2/nameofdog" 
       } 
      } 
     }, 
     : 
     : 
     ] 
    }, 
    "_links":{ 
     "self":{ 
     "href":"http://localhost:8082/animals2" 
     } 
    }, 
    "page":{ 
     "size":20, 
     "totalElements":3, 
     "totalPages":1, 
     "number":0 
    } 
} 

此攝製的代碼可以在這裏找到:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos/spring/hateoas/polymorphism/repro2

我會非常感謝,如果有人能夠解釋一種方法來使多態性與Spring HATEOAS結合工作。

回答

1

經過進一步觀察,我發現@type屬性未包含在頁面資源中的原因:type erasure。請參閱this issue

對此有一種解決方法:使用include = JsonTypeInfo.As.EXISTING_PROPERTY而不是include = JsonTypeInfo.As.PROPERTY,併爲每個返回該類型的子類添加一個屬性。它並不優雅,但它允許實現多態API。此解決方法的完整源代碼可在此處獲得:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos/spring/hateoas/polymorphism/workaround

P.S.對於那些覺得禁用SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS可以解決第一個變體中的問題:如果禁用該設置,則類型信息將被忽略,因此在序列化期間不會添加@type屬性。

+0

或者簡單地創建一個打字的頁面資源。 – zeroflagL