Spring – @RequestPart is always null with Multipart Request, Spring MVC 3.2.4

multipartform-datarestspringspring-mvc

I am developing a small RESTful service based on Spring 3.2.4 and following this article to write a custom function to send Multipart Requests.

Firstly, in the controller, I wrote the sample function to test

@RequestMapping(value = "/createUser", method = RequestMethod.POST)
public @ResponseBody String createUser(@RequestBody User user)
{
    if (user != null) {
        log.debug("Username: " + user.getUsername());
    }

    return "Successfully created!";
}

The User object contains a user information which is using Jackson JSON to get and parse data. I also used the cURL to send request and the command I tested

curl http://localhost:8080/user/createUser --data-binary @test.txt -X POST -i -H "Content-Type: application/json"

This is the text.txt

{    
    "id" : "123456",
    "username" : "YOUR_USERNAME",
    "password" : "YOUR_PASSWORD",
    "email" : "YOUR_EMAIL"
}

The application returned "Successfully created!" and logged the username. It worked fine.

Secondly, I thought everything would be simple but I was wrong. When I wrote the following function to send Multipart Requests with the User and MultipartFile objects.

@RequestMapping(
        value = "/createUser", 
        method = RequestMethod.POST, 
        consumes = {"multipart/mixed", "multipart/form-data"})
public @ResponseBody String createUser(
           @RequestPart("user") @Valid User user, 
           @RequestPart("file") MultipartFile file) {

    if (user != null) {
        log.debug("Username: " + user.getUsername());    // The username is null
    }

    return "Successfully created!";
}

I continued to use the cURL to test with the command

curl http://localhost:8080/user/createUser --data-binary @test.txt -X POST -i -H "Content-Type: multipart/mixed; boundary=4ebf00fbcf09"

And the text.txt file was changed

--4ebf00fbcf09
Content-Disposition: form-data; name="user"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit

{    
    "id" : "123456",
    "username" : "YOUR_USERNAME",
    "password" : "YOUR_PASSWORD",
    "email" : "YOUR_EMAIL"
}

--4ebf00fbcf09
Content-Disposition: form-data; name="file"; filename="no_thumb.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: base64

<... File Data ...>

--4ebf00fbcf09--

I am facing the problem that the @RequestPart is always NULL. Details:

  • The application returned "Successfully created!"
  • The User object was not null but the server logged the "Username: null" and MultipartFile object was too.

How can I fix it?

Please help me to solve this issue.

Best Answer

Answer is bit late, but could be useful still. This is what worked for me to attach both a payload and a file, with @RequestPart

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody String create(@RequestPart Blah blah, 
        @RequestPart(value = "uploadfile", required=false) MultipartFile) {...}

And with curl command below I'm able to verify this as well

curl -i -X POST -H "Content-Type: multipart/mixed" \
-F "blah={\"name\":\"mypayloadname\"};type=application/json" \
-F "uploadfile=@somevalid.zip" http://localhost:8080/url/path

Make sure you escape the payload content and somevalid.zip (second -F is optional, since required is set to false) should be there in the same directory where curl is executed or replace it with valid path to the file.