Passing Multiple Variables in @Requestbody to a Spring MVC Controller Using Ajax

Multiple ajax data to Spring MVC controller

That won't work. First lets clarify the difference between @RequestBody and @RequestParam.

The @RequestBody method parameter annotation should bind the json value in the HTTP request body to the java object by using a HttpMessageConverter. HttpMessageConverter is responsible for converting the HTTP request message to an assoicated java object. Source

And Use the @RequestParam annotation to bind request parameters to a method parameter in your controller. Source

Coming to you question...
With first ajax request you are sending JSON to your controller not request parameters, so @RequestBody is OK.

In the second ajax request also you are sending JSON but with two fields (fieldBean and id). Since @RequestBody annotated parameter is expected to hold the entire body of the request and bind to one object. You should modify the Java Object(ie TicketTemplateFieldBean) to hold id field also. This will work if you have only one argument in the controller.

Then, how to have second argument?

You cannot use two @RequestBody like :

public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, @RequestBody Long id).

as it can bind to a single object only (the body can be consumed only once), You cannot pass multiple separate JSON objects to a Spring controller. Instead you must Wrap it in a Single Object.

So your solution is to pass it as Request parameter- @RequestParam, or as a path variable - @PathVariable. Since @RequestParam and @ModelAttribute only work when data is submitted as request parameters. You should change your code like this:

@Timed
@RequestMapping(value = "saveee", method = RequestMethod.POST)
@ResponseBody
public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, @RequestParam("id") Long id) throws IOException {
//TODO smth
return JsonResultBean.success();
}

And change you request URL as follows:

$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '/organizer/api/saveee?id=10',
data: JSON.stringify(fieldBean.data),
success: function(result) {
//TODO
}
})

You can use @PathVariable like this:

@Timed
@RequestMapping(value = "saveee/{id}", method = RequestMethod.POST)
@ResponseBody
public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, @PathVariable("id") Long id) throws IOException {
//TODO smth
return JsonResultBean.success();
}

And change you request URL as follows:

$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '/organizer/api/saveee/10',
data: JSON.stringify(fieldBean.data),
success: function(result) {
//TODO
}
})

Spring MVC controller with multiple @RequestBody

Spring uses an interface called HandlerMethodArgumentResolver to decide which arguments it will pass to your handler methods. For parameters annotated with @RequestBody it uses a class called RequestResponseBodyMethodProcessor. This class basically looks in a set of HttpMessageConverter objects for one that can read the content-type of the request and can convert to the specified type. If it finds one, it passes the body of the HttpServletRequest as an InputStream to the HttpMessageConverter object.

In this case, you will probably find some JSON deserializer doing work. It very likely (seeing the IOException you get) consuming the stream and then closing it.

So really this way to do things isn't directly possible.

One solution is to make a Filter that wraps the HttpServletRequest in your own implementation that buffers the InputStream to make it reusable/re-readable as many times as are required. But again the rules for deserializing from the body might be assumed by Spring and not be what you want exactly. In this case you can create your own Annotation and HandlerMethodArgumentResolver which you then register with the application in your configuration. You can then control exactly how things are deserialized from the request body.

Another solution is to combine both MyObjectDto and messageBody into one DTO, if that makes sense to your data model (and to the Spring deserialization process).

Passing multiple data through @Requestbody Spring MVC, JSONobject is not getting updated

You need to create new JSONObject response = new JSONObject(); again in the loop for next value.
Reason: Since you are not creating a new object for each value in the list, the previous reference is getting replaced by the new value.

JSONObject response = null;
JSONObject obj = new JSONObject();
JSONArray res = new JSONArray();

int i=1;
for (AttributeList attr_list : addmodel.getAttribute()) {
response = new JSONObject();
response.put("name", attr_list.getAttribute_nm());
response.put("status", attr_list.getCategory());

res.add(response);
System.out.println("inloop--res "+res);
obj.put(i, res);//issue is here
System.out.println("inloop--obj "+obj);
i++;
}

Is it possible to map two objects from same requestBody in spring?

A HTTP request is made up of headers and body.
For a single request, you have a single request body, you can't have two. You can then parse the request body to extract different variables from it, for example if your request body is a JSON, then you can parse it and convert it into an object.

See this example, further on at section "Passing multiple json objects"

Pass Multiple data variables to the AJAX function in an easy way?

JSP Page:

    function getAssignedParticularTable(){
$('#result2').hide();
var jsonValues = {paymentType : $('#paymentType').val(), subPaymentType : $('#subPaymentType').val()};
$.ajax({
type: "POST",
url: "assignedParticularTable.html",
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(jsonValues),
success: function(response){

}
});
}

Controller Class:

@RequestMapping(value = "/assignedParticularTable.html", method = RequestMethod.POST)
public @ResponseBody String assignedParticularTable(@RequestBody HashMap<String, String> jsonValues, HttpSession session) {
System.out.println("operation: "+jsonValues);
System.out.println("operation1: "+jsonValues.get("paymentType"));
return "";
}

Spring REST multiple @RequestBody parameters, possible?

I'm pretty sure that won't work. There may be a workaround, but the much easier way would be to introduce a wrapper Object and change your signature:

public class PersonContext{
private UserContext userContext;
private Person person;
// getters and setters
}


public Person createPerson(@RequestBody PersonContext personContext)

Passing html value to spring mvc controller using ajax call

You're setting data to a string when you call JSON.stringify(). jQuery expects data to be a plain object OR a string, but assumes that if data is a string, it is a query string. You're giving it a JSON string. If you just use the plain object for data and remove "JSON.stringify", this code should work.

EDIT: The documentation for this function is here: http://api.jquery.com/jquery.ajax/

Note the section about data in the settings object.



Related Topics



Leave a reply



Submit