Java @类被添加,即使它';这是默认的impl

Java @类被添加,即使它';这是默认的impl,java,json,jackson,Java,Json,Jackson,使用Jackson(JSON/对象映射器),假设我有以下接口和类: @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

使用Jackson(JSON/对象映射器),假设我有以下接口和类:

@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”属性。有人知道我如何告诉Jackson不要为我的
鸭子添加“@class”属性吗?

您需要告诉Jackson不要为实现类包含类信息。根据文件

定义要添加什么类型信息以及在何处添加信息的更精细(更强大)的方法是使用@JsonTypeInfo注释(可能还有两个相关注释)。例如,我们可以对动物进行如下注释:

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“@CLASS”) 类动物{} (顺便说一句,这相当于键入的默认设置)

这是什么意思

  • 注释类型及其子类型的所有实例都使用这些设置(除非被其他注释覆盖)
  • 要使用的“类型标识符”是完全限定的Java类名(如“org.codehaus.jackson.sample.Animal”)
  • 类型标识符将与常规数据属性一起作为(元)属性包含;使用名称“@class”(默认使用的名称取决于类型if:对于类,它将是“@class”)
  • 使用默认类型的解析器(未添加@JsonTypeResolver);以及默认类型id解析程序(no@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);
SimpleModule SimpleModule=新的SimpleModule(“SimpleModule”,新版本(1,0,0,null));
addSerializer(新的JsonSerializer{
@凌驾
公共无效序列化(Duck Duck、JsonGenerator jgen、,
SerializerProvider提供程序)引发IOException,
JsonProcessingException{
jgen.writeStartObject();
jgen.writeStringField(“name”,duck.getName());
jgen.writeEndObject();
}
});
映射器注册表模块(simpleModule);

感谢您的精彩回答!不幸的是,你的解决方案对我不起作用。注释似乎被忽略了。也许它被超类(Animal)上的@JsonTypeInfo推翻了?我看了源代码,这应该是有效的。我将为我的答案添加自定义序列化程序。谢谢!可能我使用的是旧版本的Jackson或其他东西。请将自定义序列化程序添加到您的答案中好吗?对不起,我正在查看旧版本的页面。感谢您添加序列化程序示例!我以后再试试。