Java JSON Jackson-使用自定义序列化程序序列化多态类时出现异常
我目前正在将一些代码从jackson1.x迁移到jackson2.5json映射器,这是一个在1.x中没有的问题 这是设置(请参见下面的代码):Java JSON Jackson-使用自定义序列化程序序列化多态类时出现异常,java,json,jackson,Java,Json,Jackson,我目前正在将一些代码从jackson1.x迁移到jackson2.5json映射器,这是一个在1.x中没有的问题 这是设置(请参见下面的代码): 接口IPet 类狗实现IPet IPet用@JsonTypeInfo和@JsonSubTypes进行注释 类Human有一个IPet类型的属性,该属性用@JsonSerialize(using=CustomPetSerializer.class)注释 问题: 如果我序列化了Dog的一个实例,它将按预期工作(类型信息也由Jackson添加到json字
- 接口IPet
- 类狗实现IPet
- IPet用@JsonTypeInfo和@JsonSubTypes进行注释
- 类Human有一个IPet类型的属性,该属性用@JsonSerialize(using=CustomPetSerializer.class)注释
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=Dog.class, name="dog")
//,@JsonSubTypes.Type(value=Cat.class, name="cat")
//more subtypes here...
})
public interface IPet
{
public Long getId();
public String getPetMakes();
}
public class Dog implements IPet
{
@Override
public String getPetMakes()
{
return "Wuff!";
}
@Override
public Long getId()
{
return 777L;
}
}
public class CustomPetSerializer extends JsonSerializer<IPet>
{
@Override
public void serialize(IPet value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
{
if(value != null && value.getId() != null)
{
Map<String,Object> style = new HashMap<String,Object>();
style.put("age", "7");
gen.writeObject(style);
}
}
}
狗的执行:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=Dog.class, name="dog")
//,@JsonSubTypes.Type(value=Cat.class, name="cat")
//more subtypes here...
})
public interface IPet
{
public Long getId();
public String getPetMakes();
}
public class Dog implements IPet
{
@Override
public String getPetMakes()
{
return "Wuff!";
}
@Override
public Long getId()
{
return 777L;
}
}
public class CustomPetSerializer extends JsonSerializer<IPet>
{
@Override
public void serialize(IPet value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
{
if(value != null && value.getId() != null)
{
Map<String,Object> style = new HashMap<String,Object>();
style.put("age", "7");
gen.writeObject(style);
}
}
}
养狗的人:
public class Human
{
private IPet pet = new Dog();
@JsonSerialize(using=CustomPetSerializer.class)
public IPet getPet()
{
return pet;
}
}
CustomPetSerializer实现:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=Dog.class, name="dog")
//,@JsonSubTypes.Type(value=Cat.class, name="cat")
//more subtypes here...
})
public interface IPet
{
public Long getId();
public String getPetMakes();
}
public class Dog implements IPet
{
@Override
public String getPetMakes()
{
return "Wuff!";
}
@Override
public Long getId()
{
return 777L;
}
}
public class CustomPetSerializer extends JsonSerializer<IPet>
{
@Override
public void serialize(IPet value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
{
if(value != null && value.getId() != null)
{
Map<String,Object> style = new HashMap<String,Object>();
style.put("age", "7");
gen.writeObject(style);
}
}
}
您还需要在
CustomPetSerializer
中重写serializeWithType
,因为IPet
是多态的。这也是为什么不调用serialize
的原因。检查在调用serializeWithType
时详细解释的内容。例如,serializeWithType
实现可能如下所示:
@Override
public void serializeWithType(IPet value, JsonGenerator gen,
SerializerProvider provider, TypeSerializer typeSer)
throws IOException, JsonProcessingException {
typeSer.writeTypePrefixForObject(value, gen);
serialize(value, gen, provider); // call your customized serialize method
typeSer.writeTypeSuffixForObject(value, gen);
}
它将为您的
人类实例打印{“宠物”:{“类型”:“狗”:{“年龄”:“7”}}
。自Jackson 2.9以来writeTypePrefixForObject()
和writeTypeSuffixForObject()
已被弃用(我不清楚原因)。在新方法下,现在似乎是:
@Override
public void serializeWithType(IPet value, JsonGenerator gen,
SerializerProvider provider, TypeSerializer typeSer)
throws IOException, JsonProcessingException {
WritableTypeId typeId = typeSerializer.typeId(value, START_OBJECT);
typeSer.writeTypePrefix(gen, typeId);
serialize(value, gen, provider); // call your customized serialize method
typeSer.writeTypeSuffix(gen, typeId);
}
现在有一个额外的行,所以不确定为什么它是向前迈出的一步,也许它更有效地重用typeId
对象
来源:杰克逊的班级目前在硕士班。不是最好的源代码,但看不到任何升级文档解释该做什么。我要求在上一行澄清反对意见。它不应该是END\u OBJECT
?所以没有重用typeId
?