【问题标题】:Jackson can export to Json and Xml but not YamlJackson 可以导出到 Json 和 Xml 但不能导出到 Yaml
【发布时间】:2021-07-19 03:02:15
【问题描述】:

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

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

我已经搜索了谷歌和堆栈溢出,似乎没有其他人有类似的问题,这就是为什么我将这个问题作为一个新帖子提出。

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.access$1600(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.access$2700(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)

【问题讨论】:

    标签: java jackson yaml


    【解决方案1】:

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

    实际上,您应该删除setParent() 方法,并更改代码以使setTrue()setFalse() 也维护parent 链接,从而保持模型对象的完整性。

    parent 是派生值,即True / False 链接的反面。

    @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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多