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

我开发了一个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 for ServletContext.getRealPath()方法时,我发现了以下内容:

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

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

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

那么,我是否可以通过其他方式在这些服务器上存储文件,这些文件为getServlet().getServletContext().getRealPath("")返回getServlet().getServletContext().getRealPath("")

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

  • 它不是交易性的
  • 它会损害可移植性(如果你在集群环境中会怎样)
  • 它需要为目标位置设置外部参数

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

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

您可以通过ServletContext.gerAttribute(“javax.servlet.context.tempdir”)获取它。 但是,这些文件对Web上下文不可见(即,您无法发布简单的URL来传递这些文件),并且无法保证文件以任何方式在Web应用程序或服务器重新启动后继续存在。

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

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

但是,如果您实际上需要稍后提供该文件,您将需要一个特定于容器的机制来将外部目录“挂载”到您的Web应用程序中(Glassfish作为“备用doc根”,其他人具有相似的概念),或者您将需要编写一个servlet /filter来提供Web应用程序之外的文件存储。 这个FileServlet非常完整,正如您所看到的,创建自己的FileServlet虽然并不困难,但要做到这一点并非易事。

编辑:

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

所以:

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

并在你的路上。

再次编辑:

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

所以,绝对是使用绝对路径。 通过这种方式,您可以了解文件的位置,并且可以控制该目录的操作系统级别的访问权限(如果有必要)。