How does one specify a temp directory for file upl

2020-05-22 02:26发布

问题:

I'm using Spring Boot and need to let users upload files for processing. Right now, the file uploads to /home/username/git/myproject which is not great.

How do I make Spring put those file uploads into a temporary directory that will be periodically purged by application restart (or some other means)?

Here's what I've tried... but it doesn't work. File still saves to my working directory.

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 I'm just running my app by executing Application and it's using embedded Tomcat.

UPDATE:

Ok I've got it sorted out. I was converting the incoming MultipartFile to a normal File like so:

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;
    }

Instead, I should have been creating a new File in the designated temporary directory like this:

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;
    }

Now you may be asking, "Well what about the 'multipart.location' setting of the application.properties file?" That setting, obvious in retrospect, controls only where the ephemeral multipart file goes. If you watch that directory with a script, you'll see that a 'upload_.tmp' file appears briefly and then disappears. 'multipart.location' has nothing to do with any persistent File objects you might create.

(Note, you may be able to use the MultipartBean snippet from above instead of application.properties, but I didn't try it and why would you want to?)

To change the value of your true temp directory, you can use "-Djava.io.tmp=/path/to/dir" VM argument to specify whatever you want before running your Spring Boot application.

回答1:

in 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= ..

will be ok.



回答2:

Since you are using Spring Boot it's easier to use the MultipartProperties in your application.properties file.

From documentation properties example:

# 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.

Also you could read a detailed description from the MultipartProperties.

In order to configure to your system tmpdir, you could set:

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


回答3:

If somebody is still looking for programmatic configuration:

@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:

On windows versus linux the temp dir could have a trailing slash. Multipart held tmp files that caused new file names. creating my own tmp dir solved the issue.

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