2012-03-02 29 views
2

我使用Jackson將一些JSON反序列化爲Java POJO。我使用我的對象映射器註冊MrBean模塊,所以我只需定義一堆接口,POJO就是基於這些接口自動生成的。與Jackson(和MrBean)在反序列化時使用多態性

我想擁有一個Credentials接口,其中包含擴展它的各種憑據類型,例如, UsernamePasswordCredentials和CertificateFileCredentials。

這樣做沒有任何註釋或其他咒語,試圖使它的工作給了我下面的錯誤在我的單元測試:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "username" (Class org.codehaus.jackson.generated.SCRUBBED.Credentials), not marked as ignorable 
at [Source: [email protected]; line: 32, column: 29] (through reference chain: HostConfiguration["hostDefinitions"]->HostDefinition["credentials"]->Credentials["username"]) 

我也followed the instructions at another StackOverflow post,並且我得到了同樣的錯誤。

錯誤是有道理的; Jackson正試圖將我的JSON文件的內容映射到一個空的界面。然而,我(也許天真地)期望Jackson尋找擴展基礎Credentials接口的接口,並嘗試將這些接口中的字段與它在JSON對象中找到的字段進行匹配。

我在傑克遜wiki上看到了一些利用JSON對象中的元信息的例子,用"@class":"foo.bar.CertificateFileCredentials"裝飾一個對象,但我寧願避免這種情況,因爲我的JSON輸入將由其他服務自動生成,而其他服務不應該知道我的服務內部的任何內容。

謝謝!

回答

0

你將如何定義實際的實現類?作爲額外的接口?那些應該得到正確生成;但問題出在反序列化過程中:如果有多種選擇,解串器必須找到某種方法來找出要使用的實際類型。 爲此,建議使用@JsonTypeInfo,因爲您已經注意到了。

0

實際上,即使您不控制生成JSON的服務,該技術也可以很好地滿足您的需求。

使用@JsonTypeInfo時,保存類名是一個很好的簡單默認設置,但是Jackson可以讓您根據自己的喜好自定義它。

例如,假設服務產生JSON,看起來像這樣:

{ meows: 400, furColor: "green", species: "cat" } 

然後你就可以定義這些接口將它正確轉換。

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY,property="species") 
@JsonSubTypes({ 
     @JsonSubTypes.Type(value=Feline.class, name="cat") 
}) 
public interface Animal { 
    public String getFurColor(); 
} 

@JsonTypeName("cat") 
public interface Feline extends Animal { 
    @JsonProperty("meows") // just to have an example of a renamed property... 
    public long getMeowingVolumeInDecibels(); 
} 

然後,您應該在反序列化時自動在運行時獲取正確的java類型,並根據運行時類型自動生成「物種」屬性。希望有所幫助!

相關問題