即使它是defaultImpl,@ class也会被添加

时间:2014-02-14 08:48:30

标签: java json jackson

使用Jackson(JSON / Object映射器),让我们说我有以下接口和类:

@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,因为我为defaultImpl接口指定了Animal

现在我希望在反过来做同样的行为。

String json = objectMapper.writeValueAsString(park);

但我得到了这个JSON:

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

序列化时似乎不尊重defaultImpl!我想要" @ class"属性从输出文件中消失。有没有人知道如何告诉杰克逊不要添加" @ class"我Duck的属性?

1 个答案:

答案 0 :(得分:5)

您需要告诉Jackson不要包含实现类的类信息。根据文档,

  

更细粒度(和更强大)的方式来定义要添加的类型信息,以及在哪里使用@JsonTypeInfo注释(可能还有几个相关的注释)。例如,我们可以按如下方式注释Animal:

     

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,include = JsonTypeInfo.As.PROPERTY,property =“@ class”)    class Animal {}   (顺便提一下,它等同于输入的默认设置)。

     

这是什么意思?

     
      
  • 带注释类型的所有实例及其子类型都使用这些设置(除非被其他注释覆盖)
  •   
  • 要使用的“类型标识符”是完全限定的Java类名(如“org.codehaus.jackson.sample.Animal”)
  •   
  • 类型标识符将作为(meta-)属性包含在内,以及常规数据属性;使用名称“@class”(默认使用的名称取决于类型if:对于类,它将是“@class”)
  •   
  • 使用默认类型解析器(未添加@JsonTypeResolver);以及默认类型ID解析器(没有@JsonTypeIdResolver)
  •   

通过向Duck添加注释来完成此操作。

@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);