首页 > 解决方案 > 如何使用 Spring Boot Rest Java EE 项目正确管理对文件的写入?

问题描述

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

项目目录结构

我想从控制器 QueryMapController.java 更新我的 QueryMap.json

这是 QueryMap.json 文件

     @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 文件的控制器方法。显然一切似乎都有效。它可以正常工作,并且程序的执行就像文件已更新但实际文件未更改一样。当我重新启动服务器时,更改消失了。似乎该文件在运行时在内部某处缓存。我该如何处理。

请原谅我的自定义数据连接并编写这样的代码,它不严格遵循 MVC 准则。以这种方式编码是有原因的。

标签: javajsonspringrestspring-boot

解决方案


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


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

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

  1. 使用 .检查 json 文件的位置File.getAbsolutePath()。对我来说是<projectDir>/target/classes/QueryMap.json
  2. 检查文件的内容,它应该是原始状态。
  3. 让您的代码进行更改,然后重新检查文件内容。变化应该在那里。
  4. 停止服务器并重新构建您的项目(使用 maven mvn clean package)。
  5. 文件内容应再次处于其原始状态,因为构建过程已替换<projectDir>/target/classes/QueryMap.json<projectDir>/src/main/resources/QueryMap.json.

一种解决方案是使用类路径上的 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 相同的目录中(除非工作目录已更改)。


推荐阅读