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

Tom*_*ren 5 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; }
}
Run Code Online (Sandbox Code Playgroud)

我尝试阅读(反序列化)这段JSON:

{
    "animal": {
        "name": "Quacky"
    }
}
Run Code Online (Sandbox Code Playgroud)

使用:

Park park = objectMapper.readValue(json, Park.class);
Run Code Online (Sandbox Code Playgroud)

有用!即使没有任何类型信息(@class或@type),它也可以构造Duck因为我defaultImplAnimal接口指定了一个.

现在,我希望在相反的方式做同样的行为.

String json = objectMapper.writeValueAsString(park);
Run Code Online (Sandbox Code Playgroud)

但相反,我得到这个JSON:

{
    "animal": {
        "@class": "com.example.Duck"
        "name": "Quacky"
    }
}
Run Code Online (Sandbox Code Playgroud)

它似乎不尊重defaultImpl序列化时!我想从输出文件中删除"@class"属性.有谁知道我怎么能告诉杰克逊不要为我添加"@class"属性Duck

ste*_*own 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; }
}
Run Code Online (Sandbox Code Playgroud)

没错,补充一下

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);
Run Code Online (Sandbox Code Playgroud)