6

I am getting a problem while implementing multipart file upload using spring boot 1.5.2.

Here is the situation, I have a mapping to handle file upload process.While I start the spring server, it starts without any error. The problem is that I would either able to upload the file perfectly fine or I would get null on all attribute in FileBucket object.

This situation would stay forever if I do not shutdown the server.

  • If it could upload, it would upload fine for the rest of the time.
  • If not, it won't work until I restart the server(likely more than one time)

Here is the mapping.

@RequestMapping(value = {"/api/upload"}, method = RequestMethod.POST)
public ResponseEntity<Map<String, Integer>> upload(@Valid FileBucket fileBucket, BindingResult result) throws IOException {
        Session session = sessionFactory.openSession();
        User user = (User) session.load(User.class, getUserId());

        Map<String, Integer> model = new HashMap<String, Integer>();
        if (result.hasErrors()) {
            System.out.println("validation errors");
            System.out.println(result);
            session.close();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        } else {
            int documentId = saveDocument(fileBucket, user);
            model.put("documentId", documentId);
            session.close();
            return new ResponseEntity<Map<String, Integer>>(model, HttpStatus.OK);
        }
}

And the FileBucket object

public class FileBucketConversation {

    private MultipartFile file;

    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }
}

I have tried few ways to implement file upload, and still having the same situation.

  1. Using StandardServletMultipartResolver.

    @Bean(name = "multipartResolver")
    public StandardServletMultipartResolver resolver() {
        return new StandardServletMultipartResolver();
    }
    
  2. Using CommonsMultipartResolver v1.3.2.

    @Bean(name="multipartResolver")
    public CommonsMultipartResolver multipartResolver () {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setMaxUploadSize(MAX_FILE_SIZE);
        return resolver;
    }
    

    overriding MultipartFilter

    @Bean
    @Order(0)
    public MultipartFilter multipartFile() {
        MultipartFilter multipartFilter = new MultipartFilter();
        multipartFilter.setMultipartResolverBeanName("multipartResolver");
        return multipartFilter;
    }
    
  3. Enable spring.http.multipart in properties file

    spring.http.multipart.enabled=true
    spring.http.multipart.max-file-size=20Mb
    spring.http.multipart.max-request-size=20Mb
    

I really have no clue where to start looking. The problem happen occasionally, it do not happen every time I start the server but most of the time. Hoping some one could help me.

Thank you.

2
  • 1
    please share if you are able to resolve this problem..facing the same issue Commented May 31, 2017 at 7:07
  • 1
    I have been working a different project, I did try @Aleixs's solution but at the same time, I made a huge modification on the server and the problem never appears again. Not sure if that actually solve the problem. Sorry about that. I turned off the default multipartresolver and use CommonMultipartResolver instead. Commented Jul 28, 2017 at 5:25

2 Answers 2

4

I had the same problem, this is my solution:

In application.yml:

spring:
  http:
    multipart:
      enabled: false

In configuration:

import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
...

@Bean
public MultipartResolver multipartResolver() {
    return new CommonsMultipartResolver();
}

In RestController:

@PostMapping(value = "api/upload", consumes = "multipart/form-data") 
public void enablePurchase(@RequestHeader HttpHeaders headers,
                           FileBucketConversation fileBucketConversation) {
...
}

Important: In your client don't use any header to define the Content-type or boundary. I'm using Angular 4 and when I remove these headers from my code it works (I only set the User token):

/* DON'T USE THIS:
let boundary = "ABDCE";
headers.append("Content-type", "multipart/form-data;boundary=" + boundary);
headers.append("enctype", "multipart/form-data;boundary=" + boundary);
headers.append("boundary", boundary);
*/

I hope this help you.

Sign up to request clarification or add additional context in comments.

6 Comments

does the spring: http: multipart: enabled: false should be false or true?
It has to be false
any news on that? Did it work @AutoMEta? I have the same problem as you, but in my case, it only works on localhost and not on a remote server
nope..facing the same issue and instead i changed the project version to normal spring version (without the boot) and old spring version where it was working fine.
I am using springs 1.5.6 version and commons-fileupload 1.3.2. @RequestParam didn't work for me and had to use @RequestPart(value = "file", required = false). I had "multipartResolver" and all other suggested properties but I didn't have "spring: http: multipart: enabled: false". As soon as I added it everything worked. I never needed that explicit setting in my other project which is working on spring 1.3.5, hence i was totally oblivious of this flag.
|
1

Update for Spring Boot 2 and Spring 5

spring.http.multipart.enabled is deprecated, so forget about it.

Registering my own beans for MultipartConfigElement or MultipartResolver broke it for me.

I ended up with a @PostMapping method with a single parameter, @RequestPart(name = "file") MultipartFile file. Adding a parameter @RequestHeader HttpHeader headers helped me make sure the client was sending the required header Content-Type with a boundary.

I'm using a Node client with the form-data library and node-fetch. Here's the client code:

const formData = new FormData();
const fileMetadata = {filename: fileName, contentType: 'image/png', knownLength: fs.statSync(pathToFile)};
const formData.append('file', fs.createReadStream(pathToFile), fileMetadata);
fetch(url, {method: 'POST', body: formData});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.