Spring Download a multi-page download with a null file object

I am having a problem when implementing multi-page file upload using spring boot 1.5.2.

Here is the situation, I have a mapping to handle the file upload process. When I start the spring server, it starts without any errors. The problem is that I could either upload the file in perfect order , or I would get null for the entire attribute in the FileBucket object .

This situation would remain forever if I did not stop the server.

  • If it is downloaded, it will load for the remaining time.
  • If not, this will not work until I restart the server (maybe 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

 public class FileBucketConversation { private MultipartFile file; public MultipartFile getFile() { return file; } public void setFile(MultipartFile file) { this.file = file; } } 

I tried several ways to implement file upload and still have the same situation.

  • Using StandardServletMultipartResolver .

     @Bean(name = "multipartResolver") public StandardServletMultipartResolver resolver() { return new StandardServletMultipartResolver(); } 
  • 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; } 
  • Include spring.http.multipart in the properties file

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

I really don't know where to start looking. Sometimes this problem happens, it happens not every time I start the server, but most of the time. Hoping someone can help me.

Thanks.

+4
source share
2 answers

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: Your client does not use any header to determine the type or border of the content. I am 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); */ 

Hope this helps you.

+4
source

Update for Spring Boot 2 and Spring 5

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

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

As a result, @PostMapping method with one parameter, @RequestPart(name = "file") MultipartFile file . Adding the @RequestHeader HttpHeader headers parameter @RequestHeader HttpHeader headers helped me ensure that the client sent the required Content-Type header with a border.

I am using a Node client with a form data library and node-fetch . Here is 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}); 
0
source

All Articles