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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2395737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:58:53  来源:igfitidea点击:

Java - Relative path of a file in a java web application

javaweb-applications

提问by Yatendra Goel

I want to read a file from a java web application. I don't want to give the absolute path of the file. I just want to put the file in some directory of my web application.

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

Or

或者

It can be placed along with .war file (packaged web application).

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

What relative path to give for the file. I tried ./filename.csvbut it didn't work.

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

========

========

Updated

更新

========

I will deliver a WARfile (packaged web application) to my client. This web application will read a file (lets say SuppliedFile.csv) which will be copied to the server by the client. So I need a mechanism (that will work irrespective of whether the application server will unpak the WARor not) so that web application can read that file.

我将向WAR我的客户交付一个文件(打包的 Web 应用程序)。这个 Web 应用程序将读取一个文件(可以说SuppliedFile.csv),该文件将由客户端复制到服务器。所以我需要一种机制(无论应用程序服务器是否会解包它都可以工作WAR),以便 Web 应用程序可以读取该文件。

Note:I am not using the SuppliedFile.csvin a servlet... I am using it in a plain Java class...

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

采纳答案by Thilo

Do you really need to load it from a file? If you place it along your classes (in WEB-INF/classes) you can get an InputStream to it using the class loader:

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

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

回答by Tim Jansen

If you have a path for that file in the web server, you can get the real path in the server's file system using ServletContext.getRealPath(). Note that it is not guaranteed to work in every container (as a container is not required to unpack the WAR file and store the content in the file system - most do though). And I guess it won't work with files in /WEB-INF, as they don't have a virtual path.

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

The alternative would be to use ServletContext.getResource()which returns a URI. This URI may be a 'file:' URL, but there's no guarantee for that.

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

回答by Mark Renouf

You may be able to simply access a pre-arranged file path on the system. This is preferable since files added to the webapp directory might be lost or the webapp may not be unpacked depending on system configuration.

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

In our server, we define a system property set in the App Server's JVM which points to the "home directory" for our app's external data. Of course this requires modification of the App Server's configuration (-DAPP_HOME=... added to JVM_OPTS at startup), we do it mainly to ease testing of code run outside the context of an App Server.

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

You could just as easily retrieve a path from the servlet config:

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

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

Then retrieve this path and use it as the base path to read the file supplied by the client.

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

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;
        // ...
    }
}

As I mentioned the most likely problem you'll encounter is security restrictions. Nothing guarantees webapps can ready any files above their webapp root. But there are generally simple methods for granting exceptions for specific paths to specific webapps.

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

Regardless of the code in which you then need to access this file, since you are running within a web application you are guaranteed this is initialized first, and can stash it's value somewhere convenient for the rest of your code to refer to, as in my example or better yet, just simply pass the path as a paramete to the code which needs it.

无论您随后需要访问该文件的代码是什么,因为您在 Web 应用程序中运行,您可以保证它首先被初始化,并且可以将它的值隐藏在方便其余代码引用的地方,如我的例如或者更好的是,只需将路径作为参数传递给需要它的代码。

回答by Daniel

The alternative would be to use ServletContext.getResource() which returns a URI. This URI may be a 'file:' URL, but there's no guarantee for that.

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

You don't need it to be a file:... URL. You just need it to be a URL that your JVM can read--and it will be.

你不需要它是一个文件:... URL。您只需要它是您的 JVM 可以读取的 URL——它将会是。

回答by Hendy Irawan

Many popular Java webapps, including Jenkinsand Nexus, use this mechanism:

许多流行的 Java 网络应用程序,包括JenkinsNexus,都使用这种机制:

  1. Optionally, check a servlet context-param / init-param. This allows configuring multiple webapp instances per servlet container, using context.xmlwhich can be done by modifying the WAR or by changing server settings (in case of Tomcat).

  2. Check an environment variable(using System.getenv), if it is set, then use that folder as your application data folder. e.g. Jenkins uses JENKINS_HOMEand Nexus uses PLEXUS_NEXUS_WORK. This allows flexible configuration without any changes to WAR.

  3. Otherwise, use a subfolder inside user's home folder, e.g. $HOME/.yourapp. In Java code this will be:

    final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
    
  1. 或者,检查 servlet context-param / init-param。这允许为每个 servlet 容器配置多个 webapp 实例,使用context.xml它可以通过修改 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");
    

回答by carlos

there is another way, if you are using a container like Tomcat :

还有另一种方法,如果您使用的是 Tomcat 之类的容器:

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