1

Unfortunately this answer does not help me. The problem appears to be that the request parameter file is not present in my POST request for some reason.

I am trying to upload a file, any file whether it's a binary file or a text file, in a POST request. The REST controller reveals:

@PostMapping(WordEmbeddingApiPaths.UPLOAD_MODEL)
@RequestMapping(method=RequestMethod.POST, headers={"Content-Type=multipart/form-data"})
public ResponseEntity<WordVectorListDto> uploadModel(
        @RequestParam("file") MultipartFile file, 
        RedirectAttributes redirectAttributes) {

    LOGGER.debug("POST uploadModel");

    return new ResponseEntity<WordVectorListDto>((WordVectorListDto)null, HttpStatus.OK); 
}

and on the client I am running:

var uploader = $scope.uploader = new FileUploader({
    url: 'http://localhost:8080/rest-api/dl4j/we/uploadModel'
});

uploader.onAfterAddingFile = function($modelFile) {
    console.info('onAfterAddingFile', $modelFile);

    var fd = new FormData();

    fd.append('file', $modelFile.file);

    $http.post($modelFile.url, fd, {
        headers: {
            'Content-Type': 'multipart/form-data'
        }, 
        params: {'file' : $modelFile.file}
    })
    .then(
        function (data) {
            alert("upload success");
        }, 
        function (data, status) {
            alert("upload error");
        }
     );

};

However, I am getting 400 Bad Request as server response.

Any idea what the problem is?


Update:

I saw that an internal exception got thrown on the server side stating:

org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present

I thought that I am setting this already - how can I make this right?

Community
  • 1
  • 1
Stefan Falk
  • 23,898
  • 50
  • 191
  • 378
  • Please post the template and the code for the `FileUploader` service. – georgeawg Feb 04 '17 at 15:29
  • Possible duplicate of [How to correctly attach file to formData before POSTing to server?](http://stackoverflow.com/questions/42031959/how-to-correctly-attach-file-to-formdata-before-posting-to-server) – georgeawg Feb 04 '17 at 15:31

2 Answers2

0

Posting FormData with AngularJS

When doing a POST with a FormData API object, it is important to set the Content-Type header to undefined.

var fd = new FormData();

fd.append('file', $modelFile.file);

$http.post($modelFile.url, fd, {
    headers: {
        //'Content-Type': 'multipart/form-data'
        'Content-Type': undefined
    }, 
    //params: {'file' : $modelFile.file}
})

When the XHR send() method gets a FormData object created by the FormData API it automatically sets the content type to multipart/form-data and includes the proper boundary.

By having the AngularJS framework override the content type, the boundary is not set properly.


Debugging Small Programs

This question is an example of putting several things together without debugging each part.

This question has several unknown code components:

  • An undebugged AngularJS POST method
  • An undebugged Spring Backend
  • An undebugged mysterious AngularJS service

This answer pointed out errors with the AngularJS POST method but there are a couple of other unknowns. Is the Spring backend working properly? Is the mysterious FileUploader service being used correctly?

Debugging involves isolating unknowns and testing them separately.

Does the Angular POST method work with a known backend such as HTTP BIN - HTTP Request & Response Service?

Does the Spring backend work with an uploader that has been tested?

For more information, see How to debug small programs.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Hi! I've set it to undefined but for some reason the parameter 'file' is still not present according the the exception thrown by Spring. – Stefan Falk Feb 04 '17 at 12:04
  • `FileUploader` service comes from the `angular-file-upload` package I installed with bower. The Spring backend is fine but it complains that the request parameter `file` is not present. – Stefan Falk Feb 04 '17 at 18:44
0

if you are using @EnableAutoConfiguration then you need to do the following as discussed here https://github.com/spring-projects/spring-boot/issues/2958

  1. @EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
  2. define the following beans

    @Bean(name = "multipartResolver") public CommonsMultipartResolver commonsMultipartResolver(){ CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(50*1024*1024); return resolver ; }

    @Bean @Order(0) public MultipartFilter multipartFilter(){ MultipartFilter multipartFilter = new MultipartFilter(); multipartFilter.setMultipartResolverBeanName("multipartResolver"); return multipartFilter; }

Masud
  • 475
  • 6
  • 6