1

I use Spring MVC and in controller I have function:

@ResponseBody
@RequestMapping(value = "/json/negotiation/Supervisor.json", produces = "application/json", method = RequestMethod.POST)
public ExtResponse changeSupervisorStep(@RequestBody BatchModel<Supervisor> supervisors) {...}

From client-side I send request (use ExtJs) :

Ext.Ajax.request({
url : '/jur_rest/json/negotiation/Supervisor.json',
jsonData : { supervisors : {toInsert : [], toDelete : [], toUpdate : [] }}
});

and everything is fine, I get object with three arrays. But I would like to send once more model from client, and if I write something like that :

@ResponseBody
@RequestMapping(value = "/json/negotiation/Supervisor.json", produces = "application/json", method = RequestMethod.POST)

public ExtResponse changeSupervisorStep(@RequestBody BatchModel<Supervisor> supervisors, @RequestBody Supervisor model) { ... }

    Ext.Ajax.request({
    url : '/jur_rest/json/negotiation/Supervisor.json',
    jsonData : { supervisors : {toInsert : [], toDelete : [], toUpdate : [] }, model : {}}
    });

I get error - 400 Bad Request. What's wrong? Thanks.

EDIT:

learning Spring's @RequestBody and @RequestParam There can be only one @RequestBody parametr in controller function. How can I pass two models in one request? Combine them into one class?

Community
  • 1
  • 1
Shallow
  • 57
  • 3
  • 9
  • The difference between your two json strings is the `model: {}` part. Spring probably doesn't know how to map it. – Sotirios Delimanolis Jul 10 '13 at 13:28
  • Oops, my mistake - http://stackoverflow.com/questions/3337350/learning-springs-requestbody-and-requestparam There can be only one @RequestBody parametr, but how can I pass two models ?! – Shallow Jul 10 '13 at 13:36
  • 2
    Create a DTO containing both your `Supervisor` and the `BatchModel`. Then use that with `@RequestBody`. – Sotirios Delimanolis Jul 10 '13 at 13:41

2 Answers2

4

You can annotate as many parameters with @RequestBody as you like. But there's a catch when your request is JSON: The whole request is one object. And one object can hardly be of two different types. Depending on the circumstances your alternatives are:

  • Don't send JSON to the server, use urlencoded data instead
  • Use a DTO containing all your types
  • Write your own message converters

IMHO having two different models sent to the server is a design issue. So my sincere advice is to think about that. Assuming you can't easily change the design I would go with DTO.

a better oliver
  • 26,330
  • 2
  • 58
  • 66
  • Yes, you were right about design issue, some changes were required, and now I pass one object even without DTO, thanks. – Shallow Jul 14 '13 at 08:34
0

You could also wrap both models in wrapper which is easier than writing your own message converter or try to cram two objects in the same DTO which would give problems if both models contain an attribute with the same name.

You would have something like this:

class WrapperDTO(){
   DtoA dtoA;
   DtoB dtoB;

   public WrapperDTO(DtoA dtoA, DtoB dtoB){
    this.dtoA = dtoA;
    this.dtoB = dtoB
   }

}

In your controller method you could do:

@ResponseBody
@RequestMapping(value = "/json/negotiation/Supervisor.json", produces = 
"application/json", method = RequestMethod.POST)
public ExtResponse changeSupervisorStep(@RequestBody WrapperDTO wrapperDTO) 
{....}

DtoA and DtoB should now be filled within the wrapper. Like the previous answer. I would recommend using DTO's to process the request payload.

Markvds
  • 137
  • 10