简体   繁体   English

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

[英]Java - Relative path of a file in a java web application

I want to read a file from a java web application. 我想从Java Web应用程序读取文件。 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. 我只想将文件放在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.csv but it didn't work. 我尝试了./filename.csv但是没有用。

======== ========

Updated 更新

======== ========

I will deliver a WAR file (packaged web application) to my client. 我将向客户提供WAR文件(打包的Web应用程序)。 This web application will read a file (lets say SuppliedFile.csv ) which will be copied to the server by the client. 该Web应用程序将读取一个文件(让我们说SuppliedFile.csv ),该文件将由客户端复制到服务器。 So I need a mechanism (that will work irrespective of whether the application server will unpak the WAR or not) so that web application can read that file. 因此,我需要一种机制(无论应用程序服务器是否打开WAR都不会起作用),以便Web应用程序可以读取该文件。

Note: I am not using the SuppliedFile.csv in a servlet... I am using it in a plain Java class... 注意:我没有在servlet中使用SuppliedFile.csv ...我正在纯Java类中使用它...

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");

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. 在我们的服务器中,我们在App Server的JVM中定义一个系统属性集,该属性指向我们的应用程序外部数据的“主目录”。 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的配置(在启动时将-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. 不能保证webapp可以准备高于其webapp根目录的任何文件。 But there are generally simple methods for granting exceptions for specific paths to specific webapps. 但是通常有简单的方法可以为特定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应用程序中运行,因此可以确保首先对其进行初始化,并且可以将其值保存在便于其余代码引用的位置,例如在我的文章中。示例或更好的示例,只需将路径作为参数传递给需要它的代码即可。

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() . 如果您在Web服务器中具有该文件的路径,则可以使用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). 请注意,并不能保证在每个容器中都能正常工作(因为不需要容器即可解压缩WAR文件并将其内容存储在文件系统中-尽管大多数情况如此)。 And I guess it won't work with files in /WEB-INF, as they don't have a virtual path. 而且我猜想它不能用于/ WEB-INF中的文件,因为它们没有虚拟路径。

The alternative would be to use ServletContext.getResource() which returns a URI. 另一种方法是使用ServletContext.getResource()返回URI。 This URI may be a 'file:' URL, but there's no guarantee for that. 该URI可能是“文件:” URL,但对此不做任何保证。

Many popular Java webapps, including Jenkins and Nexus , use this mechanism: 许多流行的Java Web应用程序(包括JenkinsNexus )都使用此机制:

  1. Optionally, check a servlet context-param / init-param . (可选) 检查servlet context-param / init-param This allows configuring multiple webapp instances per servlet container, using context.xml which can be done by modifying the WAR or by changing server settings (in case of Tomcat). 这允许使用context.xml每个servlet容器中配置多个webapp实例,这可以通过修改WAR或更改服务器设置来完成(对于Tomcat)。

  2. Check an environment variable (using System.getenv ), if it is set, then use that folder as your application data folder. 检查环境变量 (使用System.getenv )(如果已设置),然后将该文件夹用作应用程序数据文件夹。 eg Jenkins uses JENKINS_HOME and Nexus uses PLEXUS_NEXUS_WORK . 例如,詹金斯使用JENKINS_HOME而Nexus使用PLEXUS_NEXUS_WORK This allows flexible configuration without any changes to WAR. 这允许灵活配置,而无需更改WAR。

  3. Otherwise, use a subfolder inside user's home folder , eg $HOME/.yourapp . 否则,请使用用户主文件夹内的子文件夹 ,例如$HOME/.yourapp In Java code this will be: 在Java代码中,这将是:

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

The alternative would be to use ServletContext.getResource() which returns a URI. 另一种方法是使用ServletContext.getResource()返回URI。 This URI may be a 'file:' URL, but there's no guarantee for that. 该URI可能是“文件:” URL,但对此不做任何保证。

You don't need it to be a file:... URL. 您不需要将其作为文件:... URL。 You just need it to be a URL that your JVM can read--and it will be. 您只需要将其作为JVM可以读取的URL,便可以了。

如果您正在使用类似Tomcat的容器,则还有另一种方法:

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

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

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