Friday, December 4, 2009

Spring @MVC Explained

SpringTravel project is used here as an example to illustrate how Spring MVC works.

The following diagram depicts the processing flow of Spring MVC.




Spring provides a Dispatcher Servlet called DispatcherServlet, which maps to an URI path pattern, in this case it is /app/*. You configure the servlet in web.xml.


    <servlet>















<servlet-name>















Spring MVC Dispatcher Servlet















</servlet-name>















<servlet-class>















org.springframework.web.servlet.DispatcherServlet















</servlet-class>















<init-param>















<param-name>contextConfigLocation</param-name>















<param-value>/WEB-INF/web-application-config.xml</param-value>















</init-param>















<load-on-startup>1</load-on-startup>















</servlet>































<servlet-mapping>















<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>















<url-pattern>/app/*</url-pattern>















</servlet-mapping>

















Controller

Controllers are annotated with @Controller. The Spring MVC Dispatcher Servlet scans for all the conroller classes. There is no need to define the controllers as beans in the conext xml file, Spring automatically does that for us. All we have to do is adding one line in the context file
web-application-config.xml, which is passed in as an initialization paramter to the Spring MVC Dispatcher Servlet.


    <context:component-scan base-package="com.springsource.springtravel.hotels" />

















Here is an example of a controller. URI path /app/hotels/* is mapped to this controller. Each handler method further narrows it down by additional URI path pattern and http method. For example search() method maps to /app/hotels/search and GET method. Handler methods have flexible signature and return type. In this example, they return three types:


  • void: view is implied by RequestToViewNameTranslator

  • string: view name

  • Model object: view is implied by RequestToViewNameTranslator

@Controller















@RequestMapping("/hotels/*")















public class HotelsController {































...































@RequestMapping(value = "index", method = RequestMethod.GET)















public void index(HotelSearchCriteria searchCriteria) {















}















































@RequestMapping(value = "search", method = RequestMethod.GET)















public String search(HotelSearchCriteria searchCriteria,















BindingResult bindResult, Model model) {















...















if (bindResult.hasErrors()) {















return "hotels/index";















} else {















model.addAttribute("hotels", searchService.search(searchCriteria));















return "hotels/search";















}















}































@RequestMapping(value = "details", method = RequestMethod.GET)















@ModelAttribute("hotel")















public Hotel details(@RequestParam("id") Long id) {















return searchService.getHotel(id);















}































}

















Model

Model in Spring MVC is actually a map, which contains beans (map values) and bean names (map keys). Model is completely separated from view and view rendering technology.

A special type of model is Form Model. Form model is specified in the form tag as following:

<form:form modelAttribute="hotelSearchCriteria" action="search" method="get">
In the handler method, form model object can be passed in as method parameter, or returned as return value. By convention-over-configuration, Spring figures out form model object name by its class name. You can always use @ModelAttribute if the names does not match.

Spring MVC vs JSF
Spring MVC is truly a MVC framework. However developers still need to deal with low level HTTP details such as URI path, form parameters to a certain degree. In the sense, Spring MVC lacks UI component model that can be found in JSF.

No comments:

Post a Comment