代码之家  ›  专栏  ›  技术社区  ›  Amit

如何通过JavaEE Web应用程序在服务器(Web容器)上存储文件?

  •  11
  • Amit  · 技术社区  · 16 年前

    我开发了一个JavaEE Web应用程序。此应用程序允许用户在浏览器的帮助下上载文件。一旦用户上传了他的文件,这个应用程序首先将上传的文件存储在服务器上(它正在服务器上运行),然后对其进行处理。

    目前,我正在服务器上存储文件,如下所示:

    try {
        // formFile represents the uploaded file
        FormFile formFile = programForm.getTheFile();
        String path = getServlet().getServletContext().getRealPath("") + "/"
            + formFile.getFileName();
        System.out.println(path);
        file = new File(path);
        outputStream = new FileOutputStream(file);
        outputStream.write(formFile.getFileData());
    }
    

    在哪里, formFile 表示上载的文件。

    现在,问题是它在一些服务器上运行良好,但是在一些服务器上 getServlet().getServletContext().getRealPath("") 正在回归 null 所以我得到的最后一条路是 null/filename 文件不存储在服务器上。

    当我检查api时 ServletContext.getRealPath() 方法,我发现如下:

    public java.lang.String getRealPath(java.lang.String path)

    返回包含给定虚拟路径的实际路径的字符串。例如,路径 "/index.html" 返回服务器文件系统上的绝对文件路径将由 "http://host/contextPath/index.html" ,其中contextPath是此ServletContext的上下文路径。

    返回的实际路径将采用与运行servlet容器的计算机和操作系统相适应的形式,包括适当的路径分隔符。如果Servlet容器由于任何原因无法将虚拟路径转换为实际路径(例如当内容从.war存档中可用时),则此方法返回null。

    那么,有没有其他方法可以让我在那些服务器上存储文件 无效的 对于 getServlet().getServletContext().getRealPath(“”)

    2 回复  |  直到 7 年前
        1
  •  13
  •   Pascal Thivent    16 年前

    不推荐从JavaEE容器写入文件系统,特别是如果需要处理写入数据时:

    • 它不是事务性的
    • 它损害了可移植性(如果您在集群环境中呢)
    • 它需要为目标位置设置外部参数

    如果这是一个选项,我会将文件存储在数据库中或使用JCR存储库(如 Jackrabbit )

        2
  •  20
  •   smilyface Saurabh Jain    7 年前

    根据规范,保证从servlet容器获得的唯一“真实”路径是临时目录。

    你可以通过 ServletContext.gerAttribute("javax.servlet.context.tempdir") . 但是,这些文件对web上下文不可见(即,您不能发布一个简单的url来传递这些文件),并且不能以任何方式保证这些文件在web应用或服务器重新启动后仍然存在。

    如果您只是需要一个地方来存储一个工作文件很短的时间,那么这将对您工作良好。

    如果你真的需要一个目录,你可以把它变成一个配置参数(一个环境变量,一个Java属性)。 java -Dyour.file.here=/tmp/files ... ),web.xml中设置的上下文参数,通过web表单存储在数据库中的配置参数,等等)。然后由部署人员为您设置此目录。

    但是,如果以后需要实际提供该文件,则需要特定于容器的机制将外部目录“挂载”到web应用程序中(glassfish作为“备用文档根”,其他的有类似的概念),或者需要编写一个servlet/过滤器来提供文件存储你的网络应用程序的侧面。这个 FileServlet 是相当完整的,正如你所看到的,创建你自己的,虽然不难,但要做正确的不是小事。

    编辑:

    基本要点是相同的,但是不要使用“getrealpath”,只需使用“getinitparameter”。

    所以:

    String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;
    

    在路上。

    再次编辑:

    至于路径的内容,我会给它一个绝对路径。否则,在执行过程中,您需要知道app服务器将其默认路径设置到哪里,并且每个app服务器很可能使用不同的目录。例如,我认为glassfish的工作目录是运行域的配置目录。不是特别明显的选择。

    所以,一定要用绝对路径。这样,您就知道文件将放在哪里,如果需要,您可以在操作系统级别上控制该目录的访问权限。

    推荐文章