在servlet应用程序中保存上传文件的推荐方法

将其存储在除 IDE 的项目文件夹(即服务器的部署文件夹)之外的可访问位置的任何位置,原因在“仅在刷新页面后可用的上传图像”的回答中提到:

  1. IDE 项目文件夹中的更改不会立即反映在服务器的工作文件夹中。IDE 中有一种后台作业,负责确保服务器的工作文件夹与上次更新同步(这在 IDE 术语中称为“发布”)。这是您看到的问题的主要原因。
  2. 在实际代码中,在某些情况下,将上传的文件存储在 Web 应用的部署文件夹中根本不起作用。某些服务器(默认情况下或按配置)不会将部署的 WAR 文件扩展到本地磁盘文件系统中,而是完全在内存中。如果不基本上编辑已部署的 WAR 文件并重新部署它,则无法在内存中创建新文件。
  3. 即使服务器将部署的 WAR 文件扩展到本地磁盘文件系统中,所有新创建的文件也会在重新部署甚至简单重新启动时丢失,因为这些新文件不是原始 WAR 文件的一部分。

对于我或其他任何人来说,只要您不使用getRealPath()方法,它在本地磁盘文件系统上的确切位置保存就真的无关紧要。在任何情况下,使用这种方法都是令人震惊的。

反过来,可以通过多种方式定义存储位置的路径。你必须自己做这一切。也许这就是引起您混淆的地方,因为您以某种方式期望服务器自动完成所有这些操作。请注意,这不会指定最终上传目的地,但案例文件大小的临时存储位置超过了内存存储阈值。@MultipartConfig(location)

因此,可以通过以下任一方式定义到最终存储位置的路径:

1、硬核版

  File uploads = new File("/path/to/uploads");

2、环境变量通过:SET UPLOAD_LOCATION=/path/to/uploads

  File uploads = new File(System.getenv("UPLOAD_LOCATION"));

3、在服务器启动过程中,通过虚拟机参数。-Dupload.location="/path/to/uploads"

  File uploads = new File(System.getProperty("upload.location"));

4、*.properties 文件条目为:upload.location=/path/to/uploads

  File uploads = new File(properties.getProperty("upload.location"));

5、web.xml<context-param> 使用名称、值:upload.location/path/to/uploads

  File uploads = new File(getServletContext().getInitParameter("upload.location"));

6、如果有的话,使用服务器提供的位置,例如在 JBoss AS/WildFly:

  File uploads = new File(System.getProperty("jboss.server.data.dir"), "uploads");

无论哪种方式,您都可以轻松地引用和保存文件,如下所示:

File file = new File(uploads, "somefilename.ext");

try (InputStream input = part.getInputStream()) {
    Files.copy(input, file.toPath());
}

或者,当您想要自动生成唯一的文件名以防止用户使用巧合的相同名称覆盖现有文件时:

File file = File.createTempFile("somefilename-", ".ext", uploads);

try (InputStream input = part.getInputStream()) {
    Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}

如何在 JSP/Servlet 中获取在 How to upload files to server using JSP/Servlet?。以及如何在 JSF 中获取回应在 How to upload file using JSF 2.2 <h:inputFile>? Where is the saved File?

注意:不要使用 Part#write(),因为它会解释相对于 中定义的临时存储位置的路径。此外,请确保在读取/写入过程中错误地使用 / 而不是 / 将字节转换为字符,从而绝对确保您不会损坏二进制文件,例如 PDF 文件或图像文件。@MultipartConfig(location)ReaderWriterInputStreamOutputStream

另请参阅:

发表回复