如何使用Spring Boot Rest Java EE项目正确管理写入文件?

时间:2018-05-23 21:08:34

标签: java json spring rest spring-boot

我正在尝试更新服务器资源文件夹中的JSON文件,以响应向我的api端点提交表单。

Project Directory Structure

我想从控制器QueryMapController.java

更新我的QueryMap.json

This is QueryMap.json file

     @CrossOrigin
   @RequestMapping("/newQuery")
    public String newQuery(@RequestParam("qid") String qid, @RequestParam("query") String query) throws Exception{

    String fileName="QueryMap.json";

     File file = new ClassPathResource(fileName).getFile();




      JSONParser parser = new JSONParser();
      FileReader fr = new FileReader(file);
     Object ob = parser.parse(fr);
     fr.close();


     JSONArray arr = (JSONArray)ob;

     JSONObject newob = new JSONObject();
     newob.put("Query_id",qid);
     newob.put("Query",query);

     arr.add(newob);


     FileWriter fw = new FileWriter(file.getAbsoluteFile(),false);
     BufferedWriter out = new BufferedWriter(fw);
     out.write(arr.toJSONString());
     out.flush();
     out.close();
     fw.close();

   return arr.toJSONString();

}

上面的代码是我想用来更新我的.json文件的Controller方法。 显然一切似乎都有效。它可以正常工作,程序执行就好像文件已更新但实际文件没有更改。当我重新启动服务器时,更改消失了。似乎文件在运行时在内部缓存。我该怎么办呢。

原谅我的自定义数据连接并编写这样的代码并不严格遵循MVC指南。它有理由以这种方式编码。

1 个答案:

答案 0 :(得分:2)

tl; dr 将要修改的文件放在类路径之外,因为在构建/打包项目时,它们会被<projectDir>/src/main/resources目录中的文件覆盖。如果你想查看代码,请检查答案的结尾。

发生这种情况的原因很可能是因为当您重新启动服务器时,您的项目将重新构建。在此过程中,每个类都被重新编译,编译后的类与所有资源(使用maven时<projectDir>/target/classes/)一起放在一个单独的目录中。这将使用<projectDir>/src/main/resources目录中的原始版本替换您更改的json文件版本。

您可以通过调试newQuery方法并执行以下步骤来验证这一点:

  1. 使用File.getAbsolutePath()检查json文件的位置。对我而言,它是<projectDir>/target/classes/QueryMap.json
  2. 检查文件的内容,它应该处于原始状态。
  3. 让您的代码执行更改,然后重新检查文件内容。应该有变化。
  4. 停止服务器并重新构建项目(使用maven mvn clean package)。
  5. 文件内容应该再次处于原始状态,因为构建过程将<projectDir>/target/classes/QueryMap.json替换为<projectDir>/src/main/resources/QueryMap.json
  6. 对此的一个解决方案是将类路径上的json文件用作默认值,并将其复制到当前工作目录,您可以在其中以任何方式更改它:

    File editableQueryMap = new File("./QueryMap.json");
    
        if (!editableQueryMap.exists()) {
          File defaultQueryMap = new ClassPathResource("QueryMap.json").getFile();
    
          try (OutputStream os = Files.newOutputStream(editableQueryMap.toPath())) {
            Files.copy(defaultQueryMap.toPath(), os);
          }
        }
    
        //do your changes with editableQueryMap here
    

    对我来说,这会将可编辑的QueryMap.json文件放在项目目录的根目录中。如果您使用jar文件,它应该将文件放在与jar相同的目录中(除非工作目录已更改)。