How to bind @RequestParam to object in spring MVC?

55,775

Solution 1

You can't, because @RequestParam just indicates, that one method's parameter should be bound to a one web request's parameter. It can't do mapping to objects. For use @RequestParam you should change ajax request:

var restDTO{
   id: 3,
   name: "hello"
}

 $.ajax({
          url: url, 
          type: 'POST',
          data: restDTO,          
          success: function(data){
             ....
          }
});

JQuery will send request as application/x-www-form-urlencoded and will process data to parameters automatically. You controller's method should look like following:

@RequestMapping("/url")
public String content(@RequestParam Long id, @RequestParam String name){...}

For automatically map parameters to object you can use @ModelAttribute annotation:

@RequestMapping("/url")
public String content(@ModelAttribute RestDTO restDTO){...}

In this case, names in javascript map should match to names of properties in RestDTO.

Generally, @ModelAttribute and @RequestBody created for same purposes: for binding data from request to method (whether objects of primitive type).

I consider, that @ModelAttribute is more convenient, when you working with html-forms and plain objects. There is ready to use Spring abilities like modelAttribute and path.

In its turn, @RequestBody more flexible, when you need manual control over data. Also, it is more convenient, when you're working with complex objects.

Personally me would prefer @RequestBody and json.

Solution 2

If you're sending your data as classic request params, you can bind to object by simply omitting the @RequestParam, so

public String content(RestDTO restDTO){...}

If you're sending json, you have to use @RequestBody.

If whysoever you're insisting on the @RequestParam, note that you can bind multiple values against a map, so

public String content(@RequestParam Map<String, String> restDTO){...}

From the @RequestParam doc

If the method parameter is Map or MultiValueMap and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.

Solution 3

In spring web you have these annotations:

RequestParam - used for get params (/path?name=)

PathVariable - used for path params (/path/{name})

RequestBody - used for post/put/patch etc. body

RequestHeader - for headers

So you can't use RequestParam for post params, doesn't matter if json or not

Share:
55,775
user3029929
Author by

user3029929

Updated on March 28, 2020

Comments

  • user3029929
    user3029929 about 4 years

    I want to make a POST request through AJAX, and I also want to bind the whole class object to the request, and I want to receive that request with @requestParam annotation. I know it can be done with @requestBody annotation, but I am curious to know: can we do it with @requestParam annotation?

    An Ajax code:

    var restDTO{
        id: 3,
        name: "hello"
    }
    
     $.ajax({
              url: url, 
              type: 'POST',
              dataType: 'json',
              contentType: 'application/json',
              mimeType: 'application/json',
              data: JSON.stringify({RestDTO : restDTO}),          
              success: function(data) 
        {
        }
    

    I do have RestDTO

    Class RestDTO 
    {
    
        int id;
        String name;
    
        //getter and setter
    
    }
    

    In controller

    public String content(@RequestParam RestDTO restDTO){...}
    

    What should I do the make this code run?

    What should I change in sending data from ajax?

    Do I need to change on server to receive an RestDto object with @requestParam annotation?

  • user3029929
    user3029929 about 8 years
    it always give NULL values of properties (id, name) in RestDTO
  • Master Slave
    Master Slave about 8 years
    sorry, missed one point. if you're sending data as json, you have to use @RequestBody
  • user3029929
    user3029929 about 8 years
    is there any way in which I can receive data with @requestParam in an class object ?? however on ajax side, I can choose anyway
  • user3029929
    user3029929 about 8 years
    Thanks for your description, I tried it and i got to know: 1. RequestBody + json. 2. ModelAttribute + application/x-www-form-urlencoded but in the end, i could not found any difference from it... I mean where to use when ?? javascript map should match to names of properties in both case
  • Master Slave
    Master Slave about 8 years
    You can bind to a map, I've added it to the answer
  • Ken Bekov
    Ken Bekov about 8 years
    @user3029929 You're right, this approaches need for same things. But, in my point of view, ModelAttribute very useful only when you working with web-forms, in other cases RequestBody more convenient.
  • a better oliver
    a better oliver about 8 years
    @ModelAttribute takes an object from or adds an object to the model. It has nothing to do with binding whatsoever.
  • Ken Bekov
    Ken Bekov about 8 years
    @zeroflagL, hmmm. Did you ever read this documentation: docs.spring.io/spring/docs/current/spring-framework-referenc‌​e/… ? Can you explain me, what does next phrase mean: ...Once present in the model, the argument’s fields should be populated from all request parameters that have matching names. This is known as data binding in Spring MVC...? Don't you know why, according to this doc BindingResult should stay right after @ModelAttribute param? It would be curious to see your explanation.
  • a better oliver
    a better oliver about 8 years
    Binding happens with or without @ModelAttribute. That's the default behavior for posted forms. You deliberately omitted the relevant part of the documentation, the two sentences before: "An @ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model.". This, and only this, is the purpose of @ModelAttribute.