繁体   English   中英

war webapp中Tomcat服务器绝对文件访问

[英]Tomcat server absolute file access in war webapp

我有一个 Spring webapp,其.war文件已上传到 Tomcat 服务器。 大多数基本功能都按预期工作 - 页面查看和表单提交。

我现在的问题是我的 webapp 需要读取和写入文件,我对如何实现这一点一无所知(文件 I/O 返回java.lang.NullPointerException )。

我使用以下代码获取Titi Wangsa Bin Damhore建议的给定文件的绝对路径,以了解相对于服务器的路径:

HttpSession session = request.getSession();
ServletContext sc = session.getServletContext();
String file = sc.getRealPath("src/test.arff");
logger.info("File path: " + file);

这是输出路径:

/home/username/tomcat/webapps/appname/src/test.arff

但是当我通过WinSCP检查文件目录时,文件的实际路径是:

/home/username/tomcat/webapps/appname/WEB-INF/classes/test.arff

这是我的问题

  1. 我如何将这些路径转换为类似C:/Users/Workspace/appname/src/test.arff (我本地机器中完美运行的原始路径)? 它的服务器是Apache Tomcat 6.0.35Apache Tomcat 6.0.35
  2. 为什么代码返回的路径与实际路径不同?
  3. 如果文件 I/O 不适用,我可以使用哪些替代方法?

PS我只需要访问两个文件(每个< 1MB),所以我认为我可能不需要使用数据库来包含它们,如本线程中减号建议的那样。

文件输入/输出

下面是我用来访问我需要的文件的代码。

BufferedWriter writer;
    try {
        URI uri = new URI("/test.arff");
        writer = new BufferedWriter(new FileWriter(
            calcModelService.getAbsolutePath() + uri));

        writer.write(data.toString());
        writer.flush();
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }

读取文件:

ServletContext application = ...;
InputStream in = null;

try {
  in = application.getResourceAtStream("/WEB-INF/web.xml"); // example

  // read your file
} finally {
  if(null != in) try { in.close(); }
   catch (IOException ioe) { /* log this */ }
}

写入文件:

ServletContext application = ...;
File tmpdir = (File)application.getAttribute("javax.servlet.context.tempdir");

if(null == tmpdir)
  throw new IllegalStateException("Container does not provide a temp dir"); // Or handle otherwise

File targetFile = new File(tmpDir, "my-temp-filename.txt");
BufferedWriter out = null;

try {
  out = new BufferedWriter(new FileWriter(targetFile));

  // write to output stream
} finally {
  if(null != out) try { out.close(); }
  catch (IOException ioe) { /* log this */ }
}

如果您不想使用 servlet 容器提供的 tmpdir,那么您应该使用一些完全在 servlet 上下文之外的地方,例如/path/to/temporary/files或类似的东西。 您绝对不想将容器的临时目录用于除真正的临时文件之外的任何内容,这些文件可以在重新部署时删除等。

这是一场战争。 您不会在其中读取/写入文件。

读取很简单:将文件放在类路径上,然后作为资源读取。

无论如何,您不应该在 Web 应用程序中编写代码,因为即使它不是WAR,上下文中的内容也可能在重新部署期间消失,或者如果您是集群的,则它可能只在一台服务器上,等等。而是文件写入应该存在于可配置的地方。

除非出于某种原因您确实需要java.io.File ,否则请从类路径加载文件并且不要担心它来自哪里。

getClass().getClassLoader().getResourceAsStream("test.arff")

我用了春天Resource分量,让我的文件路径为所建议的哈欠是这样的(test.arff位于root/srcwar部署):

Resource resource = new ClassPathResource("/test.arff");
String arffPathRaw = resource.getURI().toString(); // returns file:/path/to/file
String arffPath = arffPathRaw.replace("file:/", ""); // pure file path

接下来,我只是将arff连接到我想要的文件:

URI uri = new URI("test.arff");
BufferedWriter writer = new BufferedWriter(new FileWriter(
        arffPath + uri));

我直接在那里使用了arffPath只是为了一个简单的例子,但我做了一个函数,所以它会更方便。

  1. 文件路径实际上是/home/username/tomcat/webapps/bosom/WEB-INF/classes/test.arff所以不要害怕使用它(就像我一样)只是因为它看起来不像C:/path/to/file lmao

  2. 如果用于获取文件,请不要混淆这两个文件路径。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM