簡體   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