初学者servlet问题:访问.war中的文件,哪条路径?

时间:2010-12-27 13:01:15

标签: file servlets war

当我正在使用的第三方库尝试访问文件时,我收到“错误打开...文件...(没有这样的文件或目录)”即使我知道文件在战争。我已经尝试了打包(.war)和“爆炸”(目录)部署,文件肯定在那里。我也尝试过设置完全权限。它是在Unix(Ubuntu)上。文件是war / dict / index.sense,错误是“dict / index.sense(没有这样的文件或目录)”。

它在我的Windows计算机上运行时可以作为Eclipse的GWT应用程序在托管模式下运行,而不是在我将它传输到Unix机器进行部署时。

我的问题是:有没有人经历过这种情况和/或我应该考虑相对路径的差异,即在战争中相对文件访问的根路径是什么?

2 个答案:

答案 0 :(得分:8)

在读取资源时,不应该依赖文件IO中的相对路径。工作目录取决于应用程序的启动方式。你完全没有控制权。始终在文件IO中使用绝对路径。

正常方法是:

  • 将资源放在类路径中或将其路径添加到类路径中。然后您可以通过类加载器获取它,如下所示:

    String classPathLocation = "filename.ext";
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    InputStream input = classLoader.getResourceAsStream(classPathLocation);
    // ...
    

    请注意如何获取类加载器和资源。你不应该从当前的类中获取它,如getClass().getResourceAsStream()。在WAR中,可能存在多个类加载器的方法。当前类的类加载器可能不知道所需的资源本身,即上下文。

  • 将资源放在webcontent中(WEB-INF文件夹所在的位置以及所有其他公共Web资源)。然后你可以获得如下的绝对路径,你可以继续在通常的文件IO代码中使用它:

    String relativeWebPath = "/filename.ext";
    String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
    InputStream input = new FileInputStream(absoluteDiskPath);
    // ...
    

    请注意,这只适用于展开WAR的情况,否则只会返回null

答案 1 :(得分:0)

我欠BalusC的答案,但由于我起初并不是真的理解它,所以我简化了它:

工作目录(相对路径的起点)取决于应用程序的启动方式,因此您无法真正控制它。幸运的是,有一种方法可以获取Web应用程序根目录中任何内容的绝对路径,如下所示:

getServletContext().getRealPath("pathToAnyFileInYourWebAppDocumentRoot.ext")

(这给出了一个字符串)

这就是你要做的一切。不幸的是,这仅在您的应用程序部署为目录时有效,而不是作为.war文件(将返回null)。

(参见BalusC的另一种答案,以及答案的来源)。