使用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因为我defaultImpl为Animal接口指定了一个.
现在,我希望在相反的方式做同样的行为.
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?
您需要告诉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)
| 归档时间: |
|
| 查看次数: |
5198 次 |
| 最近记录: |