我开发了一个 Java EE 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。

那么,有没有其他方法可以将文件存储在那些正在返回的服务器上 null 为了 getServlet().getServletContext().getRealPath("")

有帮助吗?

解决方案

不建议从 Java EE 容器写入文件系统,特别是如果您需要处理写入的数据:

  • 它不是交易性的
  • 它损害了可移植性(如果您处于集群环境中怎么办)
  • 需要为目标位置设置外部参数

如果这是一个选项,我会将文件存储在数据库中或使用 JCR 存储库(例如 长耳大野兔).

其他提示

通过规范,保证您获得形成一个servlet容器唯一的“真正”的路径是一个临时目录。

您可以得到通过ServletContext.gerAttribute("javax.servlet.context.tempdir")。然而,这些文件都没有对网络上下文可见(即你不能发布一个简单的URL提供这些文件),并且这些文件未以任何方式生存的web应用程序或服务器重启保证。

如果你只需要存储工作文件的时间很短,那么这将正常工作适合你的地方。

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

然而,如果你需要真正端菜了这个文件,你要么需要一个容器特定的机制,“摩的”到您的Web应用程序的外部目录(Glassfish的作为“备用文档根”,其他人也有类似的概念),或者你需要写一个servlet /过滤器就可以提供文件存储您的Web应用程序之外。这 FileServlet 是相当完整,并且,你可以看,创建自己的,而不是困难,是不平凡的事情做对。

修改

的基本要点是相同的,但不是使用“getRealPath”,简单地使用“的getInitParameter”。

所以:

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

和用自己的方式。

修改再次:

至于路径的内容,我给它的绝对路径。否则,你就需要知道应用服务器exeuction期间设置为它的默认路径,每个应用服务器可能使用不同的目录。例如,我相信,Glassfish的工作目录是运行域的config目录。不是一个特别明显的选择。

因此,使用绝对路径,最肯定。你知道,这样其中的文件将去,你可以控制在该目录的OS级别的访问权限,如果这是必要的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top