【问题标题】:How does one specify a temp directory for file uploads in Spring Boot?如何在 Spring Boot 中为文件上传指定临时目录?
【发布时间】:2015-07-07 13:19:46
【问题描述】:

我正在使用 Spring Boot,需要让用户上传文件进行处理。现在,文件上传到 /home/username/git/myproject 这不是很好。

如何让 Spring 将这些文件上传到一个临时目录中,该目录将通过应用程序重新启动(或其他方式)定期清除?

这是我尝试过的……但它不起作用。文件仍然保存到我的工作目录中。

public class Application implements CommandLineRunner {

    /*
     * This doesn't seem to work.
     */
    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxFileSize("128KB");
        factory.setMaxRequestSize("128KB");
        factory.setLocation(System.getProperty("java.io.tmpdir"));
        return factory.createMultipartConfig();
    }

/* other stuff, main(), etc */

}

PS 我只是通过执行应用程序来运行我的应用程序,它使用的是嵌入式 Tomcat。

更新:

好的,我已经解决了。我正在将传入的 MultipartFile 转换为普通文件,如下所示:

private File convertMultipartFileToFile(MultipartFile file) throws IOException
    {    
        File convFile = new File(file.getOriginalFilename());
        convFile.createNewFile(); 
        FileOutputStream fos = new FileOutputStream(convFile); 
        fos.write(file.getBytes());
        fos.close(); 
        return convFile;
    }

相反,我应该在指定的临时目录中创建一个新文件,如下所示:

private File convertMultipartFileToFile(MultipartFile file) throws IOException
    {    
        File convFile = File.createTempFile("temp", ".xlsx"); // choose your own extension I guess? Filename accessible with convFile.getAbsolutePath()
        FileOutputStream fos = new FileOutputStream(convFile); 
        fos.write(file.getBytes());
        fos.close(); 
        return convFile;
    }

现在您可能会问,“那么 application.properties 文件的 'multipart.location' 设置怎么样?”回想起来,该设置仅控制临时多部分文件的去向。如果您watch that directory with a script,您会看到“upload_.tmp”文件短暂出现然后消失。 “multipart.location”与您可能创建的任何持久文件对象无关。

(注意,您也许可以使用上面的 MultipartBean sn-p 代替 application.properties,但我没有尝试过,您为什么要这样做?)

要更改您的真实临时目录的值,您可以在运行 Spring Boot 应用程序之前使用“-Djava.io.tmp=/path/to/dir”VM 参数指定您想要的任何内容。

【问题讨论】:

    标签: spring spring-mvc spring-boot


    【解决方案1】:

    在springboot 1.4.1.RELEASE中

    spring.http.multipart.max-file-size=10MB
    spring.http.multipart.max-request-size=10MB
    spring.http.multipart.enabled=true
    spring.http.multipart.location= ..
    

    会好的。

    【讨论】:

      【解决方案2】:

      由于您使用的是 Spring Boot,因此在您的 application.properties 文件中使用 MultipartProperties 会更容易。

      来自documentation 属性示例:

      # MULTIPART (MultipartProperties)
      multipart.enabled=true
      multipart.file-size-threshold=0 # Threshold after which files will be written to disk.
      multipart.location= # Intermediate location of uploaded files.
      multipart.max-file-size=1Mb # Max file size.
      multipart.max-request-size=10Mb # Max request size.
      

      您也可以阅读MultipartProperties 的详细说明。

      为了配置到您的系统 tmpdir,您可以设置:

      multipart.location=${java.io.tmpdir}
      

      【讨论】:

      • multipart.enabled 似乎无效。我想我已经解决了更大的问题,并将在上面发布。
      • 对于这个线程上的 cmets + Spring 文档,配置有三种风格:“spring.http.multipart.location”、“multipart.location”和“spring.servlet.multipart.location”。它们为什么以及如何不同?
      • @Sebien stackoverflow.com/q/55288931/525036。对于没有spring 前缀的那个,它似乎来自Spring Boot 1.1,如this answer中所链接。它已经在 1.5 中更改为 spring.http.multipart - 我没有检查中间版本。
      【解决方案3】:

      如果有人还在寻找程序化配置:

      @Configuration
      public class ServletConfig {
      
        @Bean
        public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) {
          final ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
          final String location = System.getProperty("java.io.tmpdir");
          final long maxFileSize = 128*1024;
          final long maxRequestSize = 128*1024;
          final MultipartConfigElement multipartConfig  = new MultipartConfigElement(location, maxFileSize, maxRequestSize, 0);
          registration.setMultipartConfig(multipartConfig);
          return registration;
        }
      
      }
      

      【讨论】:

        【解决方案4】:

        在 windows 与 linux 上,临时目录可能有一个斜杠。 Multipart 保存了导致新文件名的 tmp 文件。创建我自己的 tmp 目录解决了这个问题。

            String tempDir = System.getProperty("java.io.tmpdir");
            if(  !tempDir.endsWith("/") && !tempDir.endsWith( "\\") ) {
                tempDir = tempDir+"/";
        

        【讨论】:

        • 从 Java 7 开始,您可以通过使用 java.nio.file.Path 来避免这种情况,例如:Path.of(System.getProperty("java.io.tmpdir"))
        猜你喜欢
        • 1970-01-01
        • 2019-12-19
        • 2013-01-31
        • 2017-12-22
        • 2013-08-26
        • 2016-08-02
        • 2021-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多