Learner
Learner

Reputation: 21445

Return types in Spring MVC

I am new to Spring MVC and trying to learn the concepts from Spring MVC Docs:

A ModelAndView object, with the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.

Can someone please help me in understanding this? What does it mean that "model implicitly enriched with command object" and also the "results of @ModelAttribute annotated reference data accessor methods"?

A Model object, with the view name implicitly determined through a RequestToViewNameTranslator and the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.

How the view name is determined in Spring here?

A Map object for exposing a model, with the view name implicitly determined through a RequestToViewNameTranslator and the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.

Same is the case here, how the view name is determined?

Upvotes: 3

Views: 1296

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280179

What does it mean that "model implicitly enriched with command object" and also the "results of @ModelAttribute annotated reference data accessor methods"?

Command objects are objects created by Spring from request parameters. In other words, say you had

public ModelAndView doSomething(SomeFoo foo, @ModelAttribute SomeBar bar) {
    return new ModelAndView("view-name");
}

Spring would implicitly add the objects foo and bar are referencing to the ModelAndView returned. Note that, although SomeFoo is not annotated with @ModelAttribute, Spring will still consider it a model attribute. You'll have to look into HandlerMethodArgumentResolver to understand why.

You can also annotate methods with @ModelAttribute and those will be called and the object created added to the Model on each request handled by the @Controller your method is in. That is what is meant by results of @ModelAttribute annotated reference data accessor methods.

How the view name is determined in Spring here?

It tells you exactly how it is determined: it uses RequestToViewNameTranslator, where the default is DefaultRequestToViewNameTranslator. Read the javadoc for more details.

Same is the case here, how the view name is determined?

Same as above.


To answer the question in your comment, Spring registers a number of HandlerMethodArgumentResolver instances to resolve the arguments to pass to your @RequestMapping annotated method. It registers them in a specific order prioritizing parameters of specific types like Model, ModelMap, ModelAndView, etc. and then annotated parameters (eg. handlers for @PathVariable, @RequestParam, etc.). Spring then iterates through this list and uses the first one it finds that can handle the parameter.

One of these HandlerMethodArgumentResolver is ServletModelAttributeMethodProcessor which handles @ModelAttribute annotated parameters. Spring registers two (2) of these. One for parameters actually annotated with @ModelAttribute and one for parameters not annotated. This way you can inject your own HandlerMethodArgumentResolver to handle parameters your way.

Registration order of HandlerMethodArgumentResolver

...
ServletModelAttributeMethodProcessor for @ModelAttribute annotated parameters
...
your own HandlerMethodArgumentResolver
...
ServletModelAttributeMethodProcessor for parameters not annotated with ModelAttribute

Upvotes: 3

Sazzadur Rahaman
Sazzadur Rahaman

Reputation: 7126

Q1: what does, "model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods" mean?

Here you can see that, "The model is a Map, allowing the use of multiple objects keyed by name". We can retrieve these objects from model by their name in view page.

We generally want to pass command objects or reference data in view pages and we pass them to the view by using the above mechanism of putting them in model object.

We can explicitly put objects in model and implicitly by adding @ModelAttribute annotation to any reference data or command (or their accerssor). Beside these, the command objects we use in request serving method without marking with @ModelAttribute are also added automatically to the model.

For example see the following code block:

@ModelAttribute
public getSchool(){ //implicitly added to model by invoking this getter
   return new School();
}

@RequestMapping("/saveStudent.html")
public ModelAndView saveStudent(ClassRoom classRoom, // implicitly added to model
                                @ModelAttribute Student student, // implicitly added to model
                                Model model) {

    model.addAttribute("abc", new Abc()); //explicitly added to model
    return new ModelAndView("myView", model);
}

When you try to get objects from your view by name of "school", "classRoom", "student", "abc" respectively, you will get the reference of these objects as these are added to your model.

Q2 & Q3: How the view name is determined when we donot explicitly mention view name in the controller method's return type

Spring always prefers covention over configuration. There is a bean named RequestToViewNameTranslator. When you do not mention view name explicitly, then RequestToViewNameTranslator generates a logical view name from the URL of the request. Suppose your request url is /home.html and you did not mention any view name from the controller then RequestToViewNameTranslator generates a logical view name "home" and tries to resolve it. Here you will find it more elaborately.

Thanks and happy coding!

Upvotes: 2

Related Questions