Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring : binding object with and without @ModelAttribute

I am new in Spring and registering a user.I did like this.

@RequestMapping("/register")
    public String register(@ModelAttribute User user,BindingResult result){
       if(!result.hasErrors()){
         userSerive.register(user);
       }
     return "welcome";
}

This worked fine,but problem here is I don't need this user object in my welcome.jsp page,so why make model object heavier.So I tried without @ModelAttribute, this also works for me like below.

@RequestMapping("/register")
    public String register(User user,BindingResult result){
       if(!result.hasErrors()){
         userSerive.register(user);
       }
     return "welcome";
}

So I just want to know what are pros & cons of both and which is the best practice if I really don't need user object in jsp. Is @ModelAttribute does any other thing apart from adding object to Model,which spring implicit binding not does.Is @ModelAttribute safer way of binding or else?

I want to categories my query in following 4 type of request.what would be difference with and without @ModelAttribute if I need not to send data in view and my request is any of-

  1. query string ie form data in GET
  2. request payload or body ie form data in POST
  3. json data in ajaxified GET requst
  4. json data in POST requst- I guess this would not be bind in any of both. @RequestBody is required.
like image 948
TheCurious Avatar asked Feb 25 '17 22:02

TheCurious


People also ask

What is the use of @ModelAttribute in spring?

@ModelAttribute is an annotation that binds a method parameter or method return value to a named model attribute, and then exposes it to a web view.

What is difference between @RequestBody and @ModelAttribute?

@ModelAttribute is used for binding data from request param (in key value pairs), but @RequestBody is used for binding data from whole body of the request like POST,PUT.. request types which contains other format like json, xml.

What is the difference between @RequestParam and @ModelAttribute?

In general, @RequestParam is best for reading a small number of params. @ModelAttribute is used when you have a form with a large number of fields.

Can we use @ModelAttribute as a method argument?

As described in the Spring MVC documentation - the @ModelAttribute annotation can be used on methods or on method arguments.


2 Answers

There is probably (see below...) no difference in the behaviour between the two method signatures in your case.

Both will bind the request parameters to user and add the resulting object to the model as the attribute user - this attribute name being derived from the decapitalised type name of the method argument, User.

@ModelAttribute can be used to customise the name of the attribute, e.g. @ModelAttribute("theUser"), or to give a hint to the reader of your code that this argument is used in the view. But as you say, neither of these apply in your use case.

Exactly the same code in Spring will be used to populate the argument whether you use the @ModelAttribute annotation or not - the code in question is org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.

It therefore makes more sense to me for you to use the public String register(User user, BindingResult result) signature in your code. Adding a @ModelAttribute annotation to method arguments that are not required in the model could be confusing to people reading your code.


The slightly longer answer is that there could just about be a reason for specifying @ModelAttribute in your case - but it's quite arcane and unlikely.

Method arguments in Spring handler methods are populated by HandlerMethodArgumentResolver instances. These are configurable and are attempted in turn for each parameter.

The default handler method argument resolvers look like this (see RequestMappingHandlerAdapter):

resolvers.add(new ServletModelAttributeMethodProcessor(false));

...

resolvers.add(new ServletModelAttributeMethodProcessor(true));

If you were to add your own in the middle, e.g. a UserHandlerMethodArgumentResolver, you could then use @ModelAttribute to tell Spring to process a specific argument in the default way, rather than use your custom argument resolver class.

like image 81
ryanp Avatar answered Oct 22 '22 14:10

ryanp


This question is very useful, but I don't see the reply here answer the question properly.

I read through more threads in stackoverflow, and found this one very useful: https://stackoverflow.com/a/26916920/1542363

For myself how to decide which one to use, if I only need the binding and do not want to store the parameter object in model, then don't use @ModelAttribute.

like image 27
Sam YC Avatar answered Oct 22 '22 14:10

Sam YC