Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems sending multiple objects through POST and SPRING-MVC

I'm developing REST services which have to receive multiple info. In this case, two objects and an attribute.

This is the javascript where I'm testing the POST request

    var user = {
        username: "admin",
        password: "admin"
    };
    var userToSubscribe = {
        username: "newuser",
        password: "newpassword",
        email: "[email protected]"
    };

    var openid = "myopenid";

    $.ajax({
        url: '/myportal/rest/subscribeUser.json',
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        mimeType: 'application/json',
        data: JSON.stringify({ user: user, userToSubscribe: userToSubscribe, openid: openid})    
    });

The POST request:

    JSON


    openid
        "myopenid"

    user
        Object { username="admin", password="admin"}

    userToSubscribe
        Object { username="newuser", password="newpassword", email="[email protected]"}
    Source
    {"user":{"username":"admin","password":"admin"},"userToSubscribe":{"username":"newuser","password":"newpassword","email":"[email protected]"},"openid":"myopenid"}

And the controller which handles the POST:

    @RequestMapping(method=RequestMethod.POST, value="/subscribeUser.json")
public @ResponseBody Message subscribeUser(@RequestBody("user") User user, @RequestBody("userToSubscribe") User userToSubscribe, @RequestParam String openid){
    ...
}

And the error is

POST subscribeUser.json 400 Incorrect request localhost:8080 990 B [::1]:8080

What am i doing wrong?

Thank you

like image 518
mannuk Avatar asked Oct 29 '13 09:10

mannuk


2 Answers

The request body will contain the entire JSON content. So when you want to map the JSON, you use only one RequestBody annotated-parameter. You will have to do something like this:

public @ResponseBody Message subscribeUser(@RequestBody String str)
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(str);

And then use the convertValue method of the mapper to get your different objects from the string.

JsonNode node = mapper.readTree(str);
User theUser = mapper.convertValue(node.get("user"), User.class);

Similarly for the other objects

like image 199
Chinmay Avatar answered Nov 02 '22 14:11

Chinmay


You cannot use @ModelAttributes in a RESTful method that accepts JSON. I believe the proper method is to use @RequestBody, as done here. You will most likely need to wrap the objects in some wrapper class, but I could be wrong there as I have never personally tried to pass multiple JSON objects in one request before.

That said, I think it would be a good idea if you rethought your REST api, removing the JSON arguments and instead passing them in as part of the URI path, if possible. I would suggest reading through this blog post.

like image 36
CodeChimp Avatar answered Nov 02 '22 14:11

CodeChimp