Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I mix media types in a Spring Rest method?

I am currently trying to write a ReST method that accepts a file upload. When the user submits the file, I also want them to add a description, and some other meta data concerning the contents of the file (for instance, a "type" associated with the file's contents). I'm using the Spring MVC Controller using Spring 4.

This is an example of what I want to do:

@RequestMapping(value = "/file", method = RequestMethod.POST)
public @ResponseBody
ResponseEntity<MyFileDTO> uploadCustomAnnotationFile(
        @RequestParam("file") MultipartFile uploadFile,
        @RequestBody MyFileDetailsDTO fileDetails) {
    log.debug("This is working!");
}

However, if I attempt to invoke this method via Swagger UI, I get an unsupported media type exception:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundarycAbgNBTQ09GQTBif' not supported

I suspect that I cannot mix application/json and multipart/form-data in 1 request?

UPDATE: Based on a response by zeroflagL and following the supplied link to the documentation specific to what I'm trying to do, and using @RequestPart instead of @RequestBody, I have made a tiny amount of progress, but this still isn't working.

new method signature:

@RequestMapping(value = "/file", method = RequestMethod.POST)
public @ResponseBody
ResponseEntity<MyFileDTO> uploadCustomAnnotationFile(
        @RequestPart MultipartFile uploadFile,
        @RequestPart MyFileDetailsDTO fileDetails) {
    log.debug("This is working!");
}

new exception:

2014-12-11 09:21:45.237 [http-nio-8443-exec-8] ERROR c.i.h.c.ControllerExceptionHandler   [ControllerExceptionHandler.groovy:58] - Controller Exception
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'fileDetails' is not present.

Thanks in advance, Tonya

like image 658
Nephthys76 Avatar asked Dec 11 '14 00:12

Nephthys76


2 Answers

You can mix media types in Spring REST method. @zeroflagL/ answer maybe right. but @RequestPart works fine. Here is my code, it's nothing different with yours

@RequestMapping(value = "/interface/member/v1/register.do", method = RequestMethod.POST)
@ResponseBody
public RegisterResponse register(@RequestPart(value = "registerRequest") RegisterRequest registerRequest,
@RequestPart(value = "attachment", required = false) MultipartFile file) throws ServiceException {
    return memberV1Service.register(registerRequest, file);
}

I suggest, you should check your request. not your server side code. Here is the my test preview code (I tested in Chrome using Postman)

    POST /was/interface/member/v1/register.do HTTP/1.1
    Host: localhost:8080
    Cache-Control: no-cache

    ----WebKitFormBoundaryE19zNvXGzXaLvS5C
    Content-Disposition: form-data; name="registerRequest"

    { -- some of my json format content}
    ----WebKitFormBoundaryE19zNvXGzXaLvS5C
    Content-Disposition: form-data; name="attachment"; filename="IMG_0089.JPG"
    Content-Type: image/jpeg


    ----WebKitFormBoundaryE19zNvXGzXaLvS5C

Content-Type is missing in request.This test failed with MissingServletRequestPartException cause Required request part 'registerRequest' is not present.

You can test with RESTClient or something else and check the Content-Type is present or not.

like image 195
KiSong Kim Avatar answered Sep 23 '22 07:09

KiSong Kim


The Spring documentation explicitly explains what to do.

The idea to mix application/json and multipart/form-data is wrong, because application/json would be one part of the multipart (sic!) request.

WebKitFormBoundary leads me to think that you try to send an AJAX request from your browser and I wonder if you really send JSON. AFAIK it's not possible to explicitly add a (real) JSON part like it's shown in the Spring documentation. Maybe you can show us the client code.

Anyway you can't use @RequestBody, because that would include the files you want to upload. You would have to use @RequestPart. If you send form data - instead of JSON - alongside the files then you don't need any annotation at all.

like image 45
a better oliver Avatar answered Sep 21 '22 07:09

a better oliver