Jackson 可以导出到 Json 和 Xml 但不能导出到 Yaml

Jackson can export to Json and Xml but not Yaml

可以使用 Json 和 Xml 导出,但不能使用 yaml。 杰克逊有什么问题吗?

有什么办法可以解决杰克逊的这种情况吗?

我已经搜索了 google 和堆栈溢出,似乎没有其他人有类似的问题,这就是为什么我作为一个新人问这个问题 post.

样本 Xml:

<Node>
  <data>Does it have fur?</data>
  <false>
    <data>a dog</data>
    <parent>Does it have fur?</parent>
  </false>
  <true>
    <data>a cat</data>
    <parent>Does it have fur?</parent>
  </true>
</Node>

导出发生的代码:

package animals;

import animals.BinaryTree.BinaryTree;
import animals.BinaryTree.Node;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;

import java.io.File;
import java.io.IOException;

public class FileINOUT {
    static ObjectMapper objectMapper = new JsonMapper();
    static String ext = ".json";
    public static void export(String filename) {
        if(ext.equals(".yaml")){
            
        }
        try {
            //System.out.println(BinaryTree.getRoot());
            objectMapper.writerWithDefaultPrettyPrinter()
                    .writeValue(new File(filename + ext), BinaryTree.getRoot());
            System.out.println("File Successfully exported!");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

导出的代码:

package animals.BinaryTree;

import animals.Animal;
import com.fasterxml.jackson.annotation.*;

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "data")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Node {
    String data; //Object might be Animal or Map<String,Boolean>

    Node False;
    Node True;
    Node Parent;

    public Node(){}

    @JsonIgnore
    public Node(String qns){
        this.data = qns;

        False = null;
        True = null;
        Parent = null;
    }
    @JsonIgnore
    public Node(Animal animal){
        this.data = animal.toString();

        False = null;
        True = null;
        Parent = null;
    }
    @JsonIgnore
    @Override
    public String toString(){
        return data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getFalse() {
        return False;
    }

    public void setFalse(Node aFalse) {
        False = aFalse;
    }

    public Node getTrue() {
        return True;
    }

    public void setTrue(Node aTrue) {
        True = aTrue;
    }

    public Node getParent() {
        return Parent;
    }

    public void setParent(Node parent) {
        Parent = parent;
    }
}

错误信息:

Error:
com.fasterxml.jackson.databind.JsonMappingException: invalid character in the anchor: Does it have fur? (through reference chain: animals.BinaryTree.Node["false"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:397)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:356)
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:763)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._serializeWithObjectId(BeanSerializerBase.java:667)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:171)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1516)
    at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1217)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1026)
    at animals.FileINOUT.export(FileINOUT.java:18)
    at animals.Main.bye(Main.java:40)
    at animals.Main.main(Main.java:30)
    Suppressed: org.yaml.snakeyaml.emitter.EmitterException: expected NodeEvent, but got <org.yaml.snakeyaml.events.DocumentEndEvent()>
        at org.yaml.snakeyaml.emitter.Emitter.expectNode(Emitter.java:412)
        at org.yaml.snakeyaml.emitter.Emitter.access00(Emitter.java:62)
        at org.yaml.snakeyaml.emitter.Emitter$ExpectBlockMappingKey.expect(Emitter.java:636)
        at org.yaml.snakeyaml.emitter.Emitter.emit(Emitter.java:220)
        at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator._emit(YAMLGenerator.java:1042)
        at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator._emitEndDocument(YAMLGenerator.java:1037)
        at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.close(YAMLGenerator.java:484)
        at com.fasterxml.jackson.databind.util.ClassUtil.closeOnFailAndThrowAsIOE(ClassUtil.java:486)
        at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1219)
        ... 4 more
Caused by: org.yaml.snakeyaml.emitter.EmitterException: invalid character in the anchor: Does it have fur?
    at org.yaml.snakeyaml.emitter.Emitter.prepareAnchor(Emitter.java:901)
    at org.yaml.snakeyaml.emitter.Emitter.checkSimpleKey(Emitter.java:686)
    at org.yaml.snakeyaml.emitter.Emitter.access00(Emitter.java:62)
    at org.yaml.snakeyaml.emitter.Emitter$ExpectBlockMappingKey.expect(Emitter.java:630)
    at org.yaml.snakeyaml.emitter.Emitter$ExpectFirstBlockMappingKey.expect(Emitter.java:613)
    at org.yaml.snakeyaml.emitter.Emitter.emit(Emitter.java:220)
    at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator._emit(YAMLGenerator.java:1042)
    at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator._writeScalar(YAMLGenerator.java:875)
    at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator._writeFieldName(YAMLGenerator.java:459)
    at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.writeFieldName(YAMLGenerator.java:442)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:726)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755)

您应该忽略 parent,因为父项已经在输出中。

实际上,您应该删除 setParent() 方法,并更改代码,使 setTrue()setFalse() 也保持 parent link,保持模型对象完整性完好无损。

parent 是派生值,即 True / False link.

的反转
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Node {
    private String data; //Object might be Animal or Map<String,Boolean>

    private Node False;
    private Node True;
    private Node Parent;

    public Node(){}

    @JsonIgnore
    public Node(String qns){
        this.data = qns;
    }
    @JsonIgnore
    public Node(Animal animal){
        this.data = animal.toString();
    }
    @JsonIgnore
    @Override
    public String toString(){
        return data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getFalse() {
        return False;
    }

    public void setFalse(Node aFalse) {
        if (False != null)
            False.parent = null; // Detach old object
        False = aFalse;
        if (aFalse != null)
            aFalse.parent = this; // Attach new object
    }

    public Node getTrue() {
        return True;
    }

    public void setTrue(Node aTrue) {
        if (True != null)
            True.parent = null; // Detach old object
        True = aTrue;
        if (aTrue != null)
            aTrue.parent = this; // Attach new object
    }

    @JsonIgnore
    public Node getParent() {
        return Parent;
    }
}