2014-02-14 38 views
3

使用傑克遜(JSON的/對象映射器),比方說,我有以下的接口和類:@class得到補充,即使它的defaultImpl

@JsonTypeInfo(defaultImpl = Duck.class, use = JsonTypeInfo.Id.CLASS) 
public interface Animal { 
} 

public class Duck implements Animal { 
    private String name; 
    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 
} 

public class Park { 
    private Animal animal; 
    public Animal getAnimal() { return animal; } 
    public void setAnimal(Animal animal) { this.animal = animal; } 
} 

我嘗試讀取(反序列化)這片JSON:

{ 
    "animal": { 
     "name": "Quacky" 
    } 
} 

使用:

Park park = objectMapper.readValue(json, Park.class); 

它的工作原理!即使沒有任何類型信息(@class或@type),它也能夠構建Duck,因爲我爲Animal接口指定了defaultImpl

現在我期待着相反的行爲。

String json = objectMapper.writeValueAsString(park); 

而是我得到這個JSON:

{ 
    "animal": { 
     "@class": "com.example.Duck" 
     "name": "Quacky" 
    } 
} 

它似乎並不尊重defaultImpl序列化時!我想從輸出文件中去掉「@class」屬性。有沒有人知道我如何告訴傑克遜不要爲我的Duck添加「@class」屬性?

回答

4

您需要告訴Jackson不要包含實現類的類信息。根據文檔,

更加細化(和強大)的方式來定義什麼類型的信息添加,以及在哪裏,將使用@JsonTypeInfo註釋(可能有幾個相關的)。例如,我們可以註釋動物如下:

@JsonTypeInfo(使用= JsonTypeInfo.Id.CLASS,包括= JsonTypeInfo.As.PROPERTY,屬性= 「@類」) 類動物{} (其順便說一句,相當於打字的默認設置)。

這是什麼意思?

  • 註釋類型和所有實例及其亞型使用這些設置(除非被其他註釋覆蓋)
  • 「類型標識符」使用是完全合格的Java類的名稱(如「org.codehaus.jackson.sample .Animal「)
  • 類型標識符將作爲(meta-)屬性與常規數據屬性一起包含;使用名稱「@class」(默認使用的名稱取決於類型,如果:類爲「@class」)
  • 使用默認類型解析器(不添加@JsonTypeResolver);以及默認類型ID解析器(無@JsonTypeIdResolver)

通過添加註釋鴨做到這一點。

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) 
public class Duck implements Animal { 
    private String name; 
    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 
} 

做不到這一點,添加

SimpleModule simpleModule = new SimpleModule("SimpleModule", new Version(1,0,0,null)); 
simpleModule.addSerializer(new JsonSerializer<Duck> { 
    @Override 
    public void serialize(Duck duck, JsonGenerator jgen, 
      SerializerProvider provider) throws IOException, 
      JsonProcessingException { 
     jgen.writeStartObject(); 
     jgen.writeStringField("name", duck.getName()); 
     jgen.writeEndObject(); 
    } 
}); 
mapper.registerModule(simpleModule); 
+0

感謝您的偉大的答案!不幸的是,您的解決方案對我無效。註釋似乎被忽略。也許它被超類(動物)上的@JsonTypeInfo推翻了? –

+0

我看着源代碼,這應該已經工作。我將添加一個自定義序列化程序到我的答案。 – stevedbrown

+0

謝謝!也許我正在使用舊版本的Jackson或其他軟件。 –