提问者:小点点

Jackson-无法从使用自定义Jackson序列化程序的包装类中获取要序列化的字段


我有一个需要序列化为XML的类的小层次结构。我发现了一个过去的帖子(Jackson序列化列表,其中包含XML的多态元素),它对于让子类使用正确的子类名称序列化很有用。但是,这些子类的字段没有被序列化。这里我将提供一个示例:

public abstract class Animal {}


public class Dog extends Animal{

    public String breed;
    public String age;

    public Dog(String breed, String age) {
        this.breed = breed;
        this.age = age;
    }
}

@JsonSerialize(using = ZooSerializer.class)
public class Zoo {
    public List<Animal> animals = new ArrayList<>();
}


public class ZooSerializer extends StdSerializer<Zoo> {

    public ZooSerializer(Class<Zoo> t) {
        super(t);
    }

    public ZooSerializer() {
        this(null);
    }

    @Override
    public void serialize(Zoo zoo, JsonGenerator jg, SerializerProvider sp) throws IOException 
    {
        jg.writeStartObject();
        for (Animal animal: zoo.animals) {
            jg.writeNullField(animal.getClass().getSimpleName());
        }
        jg.writeEndObject();
    }

,然后用这个来测试:

@Test
public void Test() {
    XmlMapper xmlMapper = new XmlMapper();
    try {
    
        Zoo zoo = new Zoo();
        Dog dog = new Dog("Collie", "6");

        System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(dog));
        zoo.animals.add(dog);
        System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(zoo));

    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

,我得到以下回应:

<Dog>
  <breed>Collie</breed>
  <age>6</age>
</Dog>

<Zoo>
  <Dog/>
</Zoo>

因此,我无法理解为什么在单独流式传输狗对象时会出现狗场,而在添加到动物园对象后流式传输时不会出现狗场。如果有任何想法,我将不胜感激。非常感谢。


共1个答案

匿名用户

您可以使用< code > JSON generator # writeObjectField 方法来序列化已经定义的< code > zoo serializer # serialize 方法中的< code>Dog pojo,如下所示:

public class ZooSerializer extends StdSerializer<Zoo> {

    public ZooSerializer(Class<Zoo> t) {
        super(t);
    }
    
    public ZooSerializer() {
        this(null);
    }

    @Override
    public void serialize(Zoo zoo, JsonGenerator jg, SerializerProvider sp) throws IOException {
        jg.writeStartObject();
        for (Animal animal: zoo.animals) {
            String animalClassName = animal.getClass().getSimpleName();      
            jg.writeObjectField(animalClassName, animal);    
        }
        jg.writeEndObject();
    }
}


Output in your main example:
<Zoo>
  <Dog>
    <breed>Collie</breed>
    <age>6</age>
  </Dog>
</Zoo>

由于以这种方式编写自定义序列化程序而不使用JsonTypeInfo,如果要将获得的xml反序列化为Zoo对象,则必须编写自定义反序列化程序。