Reputation: 1269
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
Upvotes: 8
Views: 20941
Reputation: 716
You can create a java bean(POJO) containing all the objects like..
class JavaBean{
private User user;
private UserTOSubscribe userToSubscribe;
private Long openId;
// getter and setter
}
and pass this bean in to the Web service. so web service looks like..
@RequestMapping(method=RequestMethod.POST, value="/subscribeUser.json")
public @ResponseBody Message subscribeUser(@RequestBody JavaBean javaBean) {
...
}
Upvotes: 0
Reputation: 4882
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
Upvotes: 13
Reputation: 8154
You cannot use @ModelAttribute
s 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.
Upvotes: 2