Java-使用Jackson编写Json

Java-使用Jackson编写Json,java,json,jackson,overwrite,write,Java,Json,Jackson,Overwrite,Write,我目前正在为学校做一个项目,我正在尝试在json文件的末尾(在cards属性中)写一个对象,而不用使用Jackson库重写所有内容 问题是,当我尝试这样做时,我的对象被正确地写入,但它被写入文件的末尾,我尝试将它放入卡片列表中 有人有主意吗?谢谢 编辑:我已经知道如何通过重写来写入文件,为了响应老师的指示,我需要在不重写文件的情况下写入 我的Json文件: { "cards": [ { "subject": "The E

我目前正在为学校做一个项目,我正在尝试在json文件的末尾(在cards属性中)写一个对象,而不用使用Jackson库重写所有内容

问题是,当我尝试这样做时,我的对象被正确地写入,但它被写入文件的末尾,我尝试将它放入卡片列表中

有人有主意吗?谢谢


编辑:我已经知道如何通过重写来写入文件,为了响应老师的指示,我需要在不重写文件的情况下写入

我的Json文件:

{

  "cards": [
    {
      "subject": "The Earth",
      "questions": [
        {
          "challenge": "What is the highest mountain of the world?",
          "answer": "Everest"
        },
        {
          "challenge": "What is the largest ocean in the world?",
          "answer": "Pacific Ocean"
        }
      ],
      "author": "Roger",
      "theme": "IMPROBABLE"
    },

    {
      "subject": "Holidays",
      "questions": [
        {
          "challenge": "What is the most touristic country in the world?",
          "answer": "France"
        },
        {
          "challenge": "In 2019, how many pictures did vacationers take per day?",
          "answer": "55"
        }
      ],
      "author": "Roger",
      "theme": "PLEASURE"
    }
    
  ]

}
public class Main {
  
  public static void main(String[] args) {
    Question question1 = new Question("Roger", Theme.SCHOOL, "Test", "c1", "a1");
    Question question2 = new Question("Roger", Theme.SCHOOL, "Test", "c2", "a2");

    BasicCard bc = new BasicCard("Roger", Theme.SCHOOL, "Test", Arrays.asList(question1,question2));
    
    try {
          File file = new File(Constants.DECK_PATH);
          FileWriter fileWriter = new FileWriter(file, true);

          ObjectMapper mapper = new ObjectMapper();
          SequenceWriter seqWriter = mapper.writerWithDefaultPrettyPrinter().writeValues(fileWriter);
          seqWriter.write(bc);
          seqWriter.close();
      } catch (IOException e) {
          e.printStackTrace();
      }

  }

}
我的班级主要:

{

  "cards": [
    {
      "subject": "The Earth",
      "questions": [
        {
          "challenge": "What is the highest mountain of the world?",
          "answer": "Everest"
        },
        {
          "challenge": "What is the largest ocean in the world?",
          "answer": "Pacific Ocean"
        }
      ],
      "author": "Roger",
      "theme": "IMPROBABLE"
    },

    {
      "subject": "Holidays",
      "questions": [
        {
          "challenge": "What is the most touristic country in the world?",
          "answer": "France"
        },
        {
          "challenge": "In 2019, how many pictures did vacationers take per day?",
          "answer": "55"
        }
      ],
      "author": "Roger",
      "theme": "PLEASURE"
    }
    
  ]

}
public class Main {
  
  public static void main(String[] args) {
    Question question1 = new Question("Roger", Theme.SCHOOL, "Test", "c1", "a1");
    Question question2 = new Question("Roger", Theme.SCHOOL, "Test", "c2", "a2");

    BasicCard bc = new BasicCard("Roger", Theme.SCHOOL, "Test", Arrays.asList(question1,question2));
    
    try {
          File file = new File(Constants.DECK_PATH);
          FileWriter fileWriter = new FileWriter(file, true);

          ObjectMapper mapper = new ObjectMapper();
          SequenceWriter seqWriter = mapper.writerWithDefaultPrettyPrinter().writeValues(fileWriter);
          seqWriter.write(bc);
          seqWriter.close();
      } catch (IOException e) {
          e.printStackTrace();
      }

  }

}
结果

{

  "cards": [
    {
      "subject": "The Earth",
      "questions": [
        {
          "challenge": "What is the highest mountain of the world?",
          "answer": "Everest"
        },
        {
          "challenge": "What is the largest ocean in the world?",
          "answer": "Pacific Ocean"
        }
      ],
      "author": "Roger",
      "theme": "IMPROBABLE"
    },

    {
      "subject": "Holidays",
      "questions": [
        {
          "challenge": "What is the most touristic country in the world?",
          "answer": "France"
        },
        {
          "challenge": "In 2019, how many pictures did vacationers take per day?",
          "answer": "55"
        }
      ],
      "author": "Roger",
      "theme": "PLEASURE"
    }
  ]
}{
  "subject" : "Test",
  "questions" : [ {
    "challenge" : "c1",
    "answer" : "a1"
  }, {
    "challenge" : "c2",
    "answer" : "a2"
  }, {
    "challenge" : "c3",
    "answer" : "a3"
  }, {
    "challenge" : "c4",
    "answer" : "a4"
  } ],
  "author" : "Damien",
  "theme" : "SCHOOL"
}

这里的问题是两层之间的分离:

  • 文件系统,在您的情况下,通过
    FileWriter
  • 逻辑层(json),在您的案例中,通过Jackson(
    ObjectMapper
    )提供
  • 您当前将附加到较低的层(
    1.文件系统
    )。该层不知道您将要编写json。它甚至不知道json是什么。它只是让您在现有文件的末尾追加更多字节

    void write() {
        ObjectMapper om = new ObjectMapper()
        ObjectNode original = om.readValue(new File("oldFile.json"), ObjectNode)
    
        Subject s = new Subject(List.of(new Question("c1", "a1"),
                                 new Question("c2", "a2")), "Test")
    
        original.set("questions", om.valueToTree(s))
    
        om.writeValue(new File("newFile.json"), original)
    }
    
    您想要的是附加到现有的json结构中。为此,您必须读入现有对象,将所需对象附加到该对象,并通过将更新的对象写入文件系统来完全替换该文件

    publicstaticvoidmain(字符串[]args){
    问题1=新问题(“罗杰”,主题,学校,“测试”,“c1”,“a1”);
    问题2=新问题(“罗杰”,主题学校,“测试”,“c2”,“a2”);
    BasicCard bc=新BasicCard(“罗杰”,主题。学校,“测试”,数组。asList(问题1,问题2));
    ObjectMapper mapper=新的ObjectMapper();
    File File=新文件(Constants.DECK_PATH);
    试一试{
    //从文件中读取现有对象
    Map object=mapper.readValue(文件,new TypeReference(){});
    //将您的BasicCard bc添加到列表中
    object.computeIfAbsent(“cards”,k->newArrayList()).add(bc);
    //通过再次完全写入对象来重写文件内容
    writeValue(文件,对象);
    }捕获(IOE异常){
    e、 printStackTrace();
    }
    }
    
    您可以使用以下命令将json附加到现有文件中

    void write() {
        ObjectMapper om = new ObjectMapper()
        ObjectNode original = om.readValue(new File("oldFile.json"), ObjectNode)
    
        Subject s = new Subject(List.of(new Question("c1", "a1"),
                                 new Question("c2", "a2")), "Test")
    
        original.set("questions", om.valueToTree(s))
    
        om.writeValue(new File("newFile.json"), original)
    }
    

    您可以创建一个表示json字段的新类。然后,您可以读取json文件并使用objectMapper将json转换为您的对象。在此之后,您可以将卡片添加到列表中,并再次使用objectMapper将您的对象序列化为json。我想插入我的元素。我要做的正是不重写所有内容。没有其他方法吗?如果你的对象这么小(我会说低于5兆字节)->不要把它复杂化。是的,有一些方法可以在文件系统上更高效地工作(而不是每次都替换整个对象)。。。但它们不值得这么麻烦,除非你是在一个紧密的循环中进行,或者处理非常大的文件。我知道,这是我老师的指示,不是一个选择。最简单的方法是放弃漂亮的打印(每个卡片对象打印在一行中)。然后,您可以简单地在每张卡上附加一行。请注意,文件作为一个整体将不是有效的json。该文件中的每一行都将是一个有效的json对象,但整个文件不是。另一种但更高级的方法是寻找一个能够直接在文件系统上工作的库,而无需读取现有对象。一个可以通过JSONpath语法或类似语法指定“目标”,并允许直接添加到文件的现有结构中的工具。我只是在谷歌上搜索了一下,发现了一个名为
    jq
    的命令行工具。有一些java包装器使用围绕它构建的JNI。看起来jq可以使用像
    jq.cards+={..your json card object..}
    这样的命令来做你想做的事情,我已经知道如何通过重写文件来写入文件,为了响应老师的指示,我需要在不重写文件的情况下执行该操作。无论是重写文件还是重新创建新文件。我不能完全肯定。。但我认为像JQ这样的工具将验证整个文件并重新创建临时文件,然后在EndHAB中添加一些东西可以将原始JSON视为纯文本文件,用逗号>代码替换最后的<代码> } /代码>,<代码>您的新JSON部分,后面跟着<代码> } /代码>