Java - Java Web应用程序中文件的相对路径

时间:2010-03-07 09:21:01

标签: java web-applications

我想从java Web应用程序中读取文件。我不想给出文件的绝对路径。我只想将文件放在我的Web应用程序的某个目录中。

或者

它可以与.war文件(打包的Web应用程序)一起放置。

为文件提供什么相对路径。我试过了./filename.csv,但它没有用。

======

更新

======

我将向客户端发送一个WAR文件(打包的Web应用程序)。此Web应用程序将读取一个文件(简称SuppliedFile.csv),该文件将由客户端复制到服务器。因此,我需要一种机制(无论应用程序服务器是否会取消WAR)都可以使用,以便Web应用程序可以读取该文件。

注意:的 我没有在servlet中使用SuppliedFile.csv ...我在普通的Java类中使用它...

6 个答案:

答案 0 :(得分:28)

你真的需要从文件中加载吗?如果你把它放在你的类(在WEB-INF / classes中),你可以使用类加载器获得一个InputStream:

InputStream csv = 
   SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");

答案 1 :(得分:14)

您可以简单地访问系统上预先安排的文件路径。这是首选,因为添加到webapp目录的文件可能会丢失,或者webapp可能无法解压缩,具体取决于系统配置。

在我们的服务器中,我们在App Server的JVM中定义一个系统属性集,该属性指向应用程序外部数据的“主目录”。当然这需要修改App Server的配置(-DAPP_HOME = ...在启动时添加到JVM_OPTS),我们这样做主要是为了简化在App Server上下文之外运行的代码的测试。

您可以轻松地从servlet配置中检索路径:

<web-app>
<context-param>
    <param-name>MyAppHome</param-name>
    <param-value>/usr/share/myapp</param-value>
</context-param>
...
</web-app>

然后检索此路径并将其用作读取客户端提供的文件的基本路径。

public class MyAppConfig implements ServletContextListener {

    // NOTE: static references are not a great idea, shown here for simplicity
    static File appHome;
    static File customerDataFile;

    public void contextInitialized(ServletContextEvent e) {

        appHome = new File(e.getServletContext().getInitParameter("MyAppHome"));
        File customerDataFile = new File(appHome, "SuppliedFile.csv");
    }
}

class DataProcessor {
    public void processData() {
        File dataFile = MyAppConfig.customerDataFile;
        // ...
    }
}

正如我所提到的,您遇到的最可能的问题是安全限制。没有什么能保证webapps可以在webapp根目录之上准备好任何文件。但是,通常有一些简单的方法可以为特定Web应用程序的特定路径授予例外。

无论您需要访问此文件的代码如何,因为您在Web应用程序中运行,所以您可以保证首先对其进行初始化,并且可以将其值隐藏在方便其他代码引用的位置,就像在我的例子中或者更好的那样,只需将路径作为参数传递给需要它的代码。

答案 2 :(得分:9)

如果您在Web服务器中有该文件的路径,则可以使用ServletContext.getRealPath()获取服务器文件系统中的实际路径。请注意,不保证在每个容器中都可以工作(因为不需要容器来解压缩WAR文件并将内容存储在文件系统中 - 尽管如此)。我想它不适用于/ WEB-INF中的文件,因为它们没有虚拟路径。

另一种方法是使用返回URI的ServletContext.getResource()。这个URI可能是'file:'URL,但不能保证。

答案 3 :(得分:3)

许多流行的Java Web应用程序,包括JenkinsNexus,都使用此机制:

  1. (可选)检查servlet context-param / init-param 。这允许使用context.xml为每个servlet容器配置多个webapp实例,这可以通过修改WAR或更改服务器设置(如果是Tomcat)来完成。

  2. 检查环境变量(使用System.getenv),如果已设置,则使用该文件夹作为应用程序数据文件夹。例如Jenkins使用JENKINS_HOME,Nexus使用PLEXUS_NEXUS_WORK。这允许灵活配置而不需要对WAR进行任何更改。

  3. 否则,在用户的主文件夹中使用子文件夹,例如$HOME/.yourapp。在Java代码中,这将是:

    final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
    

答案 4 :(得分:1)

  

另一种方法是使用返回URI的ServletContext.getResource()。这个URI   可能是'file:'URL,但不能保证。

您不需要它是文件:... URL。您只需将它作为JVM即可的URL 阅读 - 它将会是。

答案 5 :(得分:-9)

还有另一种方式, 如果您使用像Tomcat这样的容器:

String textPath = "http://localhost:8080/NameOfWebapp/resources/images/file.txt";