Java – Post multipart file and json in one request with @RequestPart from angular4

angularhttpjavaspringspring-boot

I use Jhipster and this is a controller method:

Controller:

@RequestMapping(value = UPLOAD_URL, method = {RequestMethod.POST},
        headers = {"content-type=multipart/mixed", "content-type=multipart/form-data"},
        consumes = {"multipart/form-data"})
    public ResponseEntity<?> uploadWithMetaData(@RequestPart(value = "file") MultipartFile file,
                                                @RequestPart(value = "documentDTO") DocumentDTO documentDTO,
                                                Locale locale) throws IOException, URISyntaxException, JSONException {
  // business logic
}

Essentially I want to post a file and also a json object.

I my integration test, I can verify that it works as expected:

Integration test:

DocumentDTO documentDTO = getDocumentDTOMockFile();
Long originId = originRepository.findAll().stream().findFirst().get().getId();
documentDTO.setOriginId(originId);

MockMultipartFile jsonFile = new MockMultipartFile("documentDTO", "", "application/json",
jsonUtils.toJson(documentDTO, null).getBytes());

restClientMockMvc
      .perform(MockMvcRequestBuilders.fileUpload("/api/v1/documents/upload")
                .file(fstmp)
                .file(jsonFile))
            .andDo(MockMvcResultHandlers.log())
            .andExpect(status().isOk());

}

Angular frontend:

let fd: FormData = new FormData();
let file = fileForm.files[0];

fd.append("file", file);

let documentDTO = JSON.stringify(document);

fd.append("documentDTO",new Blob([JSON.stringify({
     "documentDTO": documentDTO})], {
         type: "application/json"
    })
);

his.httpClient.post("/api/v1/documents/upload", fd ).subscribe(request => {
   console.log("request", request);
});

I got an interceptor that sets the content-type in the request headers to:

Content-Type:multipart/form-data; boundary=—-WebKitFormBoundary4PnIOSOLe5Djj95R

This is how the Request payload looks like:

enter image description here

This is the spring boot log message:

Resolved exception caused by Handler execution: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present

This is the response I see in the browser:

{
  "type" : "http://www.jhipster.tech/problem/problem-with-message",
  "title" : "Bad Request",
  "status" : 400,
  "detail" : "Required request part 'file' is not present",
  "path" : "///api/v1/documents/upload",
  "message" : "error.http.400"
}

What I've tried:

  • setting content-type to 'Content-Type' : 'multipart/mixed' => result same
  • Creating a pojo with the dto and the file, using @ModelAttribute => same error
  • Then I checked if I got a Multipart Resolver, got it

I'm out of ideas, someone any suggestions?

Best Answer

Post as a multipart-form from the JavaScript and use something like this:

    final WebRequest webRequest,
    @RequestParam("fileContent") final MultipartFile fileContent,
    @RequestParam("inputJson") String inputJsonString

as the parameters.

The WebRequest is useful if you need to access the session.