Spring MVC

1,799 views

Published on

Spring MVC

Published in: Technology
  • Be the first to comment

Spring MVC

  1. 1. Enhancing Web Development
  2. 2. Life Cycle of Spring MVC Request All the requests are passed through a single frontcontroller servlet called the DispatcherServlet. The DispatcherServlet’s job is to send the request on toa Spring MVC controller, were an application may haveseveral controllers. The DispatcherServlet consults one or more handlermappings which determine appropriate controllerbased on the request URL. DispatcherServlet then sends the request on its to thechosen controller.
  3. 3. Life Cycle of Spring MVC Request
  4. 4. Life Cycle of Spring MVC Request At the controller, the request’s payload is dropped offand the information is processed. The logic in the controller comes up with the Resultinformation after processing referred as model. At last the controller packages up the model data andthe name of a view for display into a ModelAndViewobject. The ModelAndView object contains model data andthe logical name to be used to lookup for actual htmlview. The controller sends the request and theModelAndView object back to the DispatcherServlet.
  5. 5. Life Cycle of Spring MVC Request The DispatcherServlet asks a View Resolver to helpfind the actual JSP View. The DispatcherServlet then delivers the model data tothe View implementation thus completing therequest’s job.
  6. 6. DispatcherServlet Configuration The DispatcherServlet must be configured in the webapplication’s web.xml file. <servlet> <servlet-name>roadrantz</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> Adding <servlet-mapping> to web.xml enablesDispatcherServlet to indiacte the URL’s it will be handling. <servlet-mapping> <servlet-name>roadrantz</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
  7. 7. DispatcherServlet Configuration By default, when DispatcherServlet is loaded, it loadsthe Spring application context from an XML file whosename is based on the name of the servlet <servlet-name>. Also application context can be split across multipleXML files based on various application layers. It help keeping the maintenance easier and allowingfiles to be focused on a single layer of the application.
  8. 8. Context Loader Configuration A context loader is added to web.xml as it loadscontext configuration files in addition to the one thatDispatcherServlet loads. Context loader is a servlet listener calledContextLoaderListener. <listener> <listener-class>org.springframework. web.context.ContextLoaderListener</listener-class> </listener>
  9. 9. Context Loader Configuration Context Loader configures the location of the Springconfiguration file(s) to load which is “/WEB-INF/applicationContext.xml” by default. The contextConfigLocation parameter in the servletcontext specifies one or more Spring configuration files forthe context loader to load. <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/roadrantz-service.xml /WEB-INF/roadrantz-data.xml /WEB-INF/roadrantz-security.xml </param-value> </context-param>
  10. 10. Steps to Build Homepage in Spring MVC Write the controller class that performs the logicbehind the homepage. The logic involves using aRantService to retrieve the list of recent rants. Configure the controller in the DispatcherServlet’scontext configuration file (roadrantz-servlet.xml). Configure a view resolver to tie the controller to theJSP. Write the JSP that will render the homepage to theuser.
  11. 11. Building the controller public class HomePageController extends AbstractController { public HomePageController() {} protected ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception { List recentRants = rantService.getRecentRants(); return new ModelAndView("home", "rants", recentRants); } private RantService rantService; public void setRantService(RantService rantService) { this.rantService = rantService; } }
  12. 12. ModelAndView A ModelAndView object fully encapsulates the view andmodel data that is to be displayed by the view. The ModelAndView object is constructed as follows:new ModelAndView("home", "rants", recentRants); The first parameter of the ModelAndView constructor isthe logical name of a view component which is used todisplay the output from the controller. A view resolver will use the view name to look up the actualView object. The next two parameters which acts as name-value pairrepresent the model object that will be passed to the view.
  13. 13. Configuring the Controller <bean name="/home.htm" class="com.roadrantz.mvc.HomePageController"> <property name="rantService" ref="rantService" /> </bean> Here, the rantService property is injected with animplementation of the RantService interface. Also bean name is specified instead of bean id as the URLpattern is not valid for bean id attribute. The name attribute serves a double duty as both the nameof the bean and a URL pattern for requests that should behandled by the controller. It can be avoided by configuringa handlermapping bean. The default handler mapping used by DispatcherServlet isBeanNameUrlHandlerMapping, which uses the base nameas the URL pattern.
  14. 14. View Resolver Declaration A view resolver’s job is to take the view name returned in theModelAndView and map it to a view (i.e. a JSP file that rendersthe webpage). InternalResourceViewResolver prefixes the view name returnedin the ModelAndView with the value of its prefix property andsuffixes it with the value from its suffix property. <bean id="viewResolver“ class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean>
  15. 15. Creating JSP Page <%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <html> <head><title>Rantz</title></head> <body> <h2>Welcome to RoadRantz!</h2> <h3>Recent rantz:</h3> <ul> <c:forEach items="${rants}" var="rant"> <li><c:out value="${rant.vehicle.state}"/> / <c:out value="${rant.vehicle.plateNumber}"/> -- <c:out value="${rant.rantText}"/> </li> </c:forEach> </ul> </body> </html>
  16. 16. Summary of Spring MVC Process DispatcherServlet receives a request whose URL pattern is/home.htm. DispatcherServlet consults BeanNameUrlHandlerMapping tofind a controller whose bean name is /home.htm; it finds theHomePageController bean. DispatcherServlet dispatches the request toHomePageController for processing. HomePageController returns a ModelAndView object with alogical view name of home and a list of rants in a property calledrants DispatcherServlet consults its view resolver (configured asInternalResourceViewResolver) to find a view whose logicalname is home. InternalResourceViewResolver returns the pathto /WEB-INF/jsp/home.jsp. DispatcherServlet forwards the request to the JSP at /WEB-INF/jsp/home.jsp to render the homepage to the user
  17. 17. Mapping requests to controllers Handler mappings help DispatcherServlet to figure out whichcontroller the request should be sent to. Handler mappings typically map a specific controller bean to aURL pattern. All of Spring MVC’s handler mappings implement theorg.springframework.web.servlet.HandlerMapping interface. All of the Spring handler mapping classes implement Spring’sOrdered interface. Hence multiple handler mappings can be declared in theapplication and set their order properties to indicate which hasprecedence with relation to the others. The lower the value of the order property, the higher the priority. <bean id="beanNameUrlMapping“class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="order"><value>1</value></property> </bean>
  18. 18. Spring MVC Handler mappingsHandler mapping How it maps requests to controllersBeanNameUrlHandlerMapping Maps controllers to URLs that are basedon the controllers’ bean name.SimpleUrlHandlerMapping Maps controllers to URLs using aproperty collection defined in the Springapplication context.ControllerClassNameHandlerMapping Maps controllers to URLs by using thecontroller’s class name as the basis for theURL.CommonsPathMapHandlerMapping Maps controllers to URLs using source-level metadata placed in the controllercode. The metadata is defined usingJakarta Commons Attributes(http://jakarta.apache.org/commons/attributes).
  19. 19. SimpleUrlHandlerMapping It allows to map URL patterns directly to controllerswithout having to name the beans in a special way. <bean id="simpleUrlMapping"class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/home.htm">homePageController</prop> <prop key="/rantsForVehicle.htm“>rantsForVehicleController</prop> <prop key="/rantsForVehicle.rss“>rantsForVehicleControllerRss</prop> <prop key="/rantsForDay.htm">rantsForDayController</prop> <prop key="/login.htm">loginController</prop> <prop key="/register.htm">registerMotoristController</prop> <prop key="/addRant.htm">addRantController</prop> </props> </property> </bean>
  20. 20. SimpleUrlHandlerMapping SimpleUrlHandlerMapping’s mappings property iswired with a java.util.Properties using <props>. The key attribute of each <prop> element is a URLpattern. All the URL patterns are relative to DispatcherServlet’s<servlet-mapping>. The value of each <prop> is the bean name of acontroller that will handle requests to the URLpattern.
  21. 21. ControllerClassNameHandlerMapping It is used when mapping the controllers to URLpatterns is quite similar to the class names of thecontrollers. <bean id="urlMapping”class="org.springframework.web.servlet.mvc.ControllerClassNameHandlerMapping"/> It enables the DispatcherServlet to map URL patternsto the controllers following a simple convention. Spring automatically maps the controllers to URLpatterns that are based on the controller’s class name.
  22. 22. Metadata Map Controllers The CommonsPathMapHandlerMapping considerssource-level metadata placed in a controller’s sourcecode to determine the URL mapping. The metadata is expected to be anorg.springframework.web.servlet.handler.commonsattributes.PathMap attribute compiled into the controllerusing the Jakarta Commons Attributes compiler. <bean id="urlMapping"class="org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping"/>
  23. 23. Metadata Map Controllers Each of the Controllers is tagged with a PathMap attribute todeclare the URL pattern for the controller. For example, to map HomePageController to /home.htm, tagHomePageController as follows: /** * @@org.springframework.web.servlet.handler. commonsattributes.PathMap("/home.htm") */ public class HomePageController extends AbstractController { ….. } The build need to be set up to include the Commons Attributescompiler so that the attributes will be compiled into theapplication code.
  24. 24. Handling requests with controllers The Controller interface is at the top of the controllerhierarchy. Any class implementing Controller interface can beused to handle requests through the Spring MVC.
  25. 25. Spring MVC Controller ClassesControllertypeClasses Useful when…View ParameterizableViewControllerUrlFilenameViewControllerController only needs to displaya static view—no processing ordata retrieval is neededSimple Controller (interface)AbstractControllerController is extremely simple,requiring little morefunctionality than is afforded bybasic Java servlets.Throwaway ThrowawayController A simple way to handle requestsas commands (in a mannersimilar to WebWorkActions).Multiaction MultiActionController Application has severalactions that perform similar orrelated logic.
  26. 26. Spring MVC Controller ClassesControllertypeClasses Useful when…Command BaseCommandControllerAbstractCommandControllerController will accept one ormore parameters from therequest and bind them to anobject. Also capable ofperforming parametervalidation.Form AbstractFormControllerSimpleFormControllerTo display an entry form to theuser and also process the dataentered into the formWizard AbstractWizardFormController To walk the user through acomplex, multipage entry formthat ultimately gets processedas a single form.
  27. 27. Processing commands Command controller are used to perform work basedon parameters such as binding parameters to businessobjects E.g. AbstractCommandController. Command controllers can automatically bind requestparameters to a command object. They can also be wired to plug in validators to ensurethat the parameters are valid.
  28. 28. AbstractCommandController public class RantsForVehicleController extends AbstractCommandController { public RantsForVehicleController() { setCommandClass(Vehicle.class); setCommandName("vehicle"); } protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { Vehicle vehicle = (Vehicle) command; List vehicleRants = rantService.getRantsForVehicle(vehicle)); Map model = errors.getModel(); model.put("rants",4 rantService.getRantsForVehicle(vehicle)); model.put("vehicle", vehicle); return new ModelAndView("vehicleRants", model); } private RantService rantService; public void setRantService(RantService rantService) { this.rantService = rantService; }
  29. 29. Command Controller The handle() method of is the main execution methodfor AbstractCommandController. The handle() method takes an Object that is thecontroller’s command along with HttpServletRequestand HttpServletResponse. A command object is a bean (POJO) that is meant tohold request parameters for easy access. Before the handle() method is called, Spring willattempt to match any parameters passed in the requestto properties in the command object.
  30. 30. Form Controller Form Controller is a single controller to handle both form displayand form processing. Form controllers extend the command controllers by adding thefunctionality to display a form when an HTTP GET request isreceived and process the form when an HTTP POST is received. Further, if any errors occur in processing the form, the controllerwill know to redisplay the form so that the user can correct theerrors and resubmit.
  31. 31.  public class AddRantFormController extends SimpleFormController { private static final String[] ALL_STATES = { "AL", "CA", "FL", "IL", "OH"}; public AddRantFormController() { setCommandClass(Rant.class); setCommandName("rant"); } protected Object formBackingObject(HttpServletRequest request) throws Exception { Rant rantForm = (Rant) super.formBackingObject(request); rantForm.setVehicle(new Vehicle()); return rantForm; } protected Map referenceData(HttpServletRequest request) throws Exception { Map referenceData = new HashMap(); referenceData.put("states", ALL_STATES); return referenceData; } protected ModelAndView onSubmit(Object command, BindException bindException) throws Exception { Rant rant = (Rant) command; rantService.addRant(rant); return new ModelAndView(getSuccessView()); } }Form Controller Example
  32. 32. Form Controller When the form controller receives an HTTP GETrequest, it will direct the request to the form view. When the form controller receives an HTTP POSTrequest, the onSubmit() method will process the formsubmission. The form uses the nested property within a commandclass instance as part of the form-backing object.hence, the formBackingObject() method is overiddento set this property. The onSubmit() method handles the form submission(an HTTP POST request) by passing the commandobject (which is an instance of Rant) to the method ofthe injected Service Object reference.
  33. 33. Form Controller The form controller in the context configuration file as follows: <bean id="addRantController" class="com.roadrantz.mvc.AddRantFormController"> <property name="formView" value="addRant" /> <property name="successView" value="rantAdded" /> <property name="rantService" ref="rantService" /> </bean> The formView property is the logical name of a view to displaywhen the controller receives an HTTP GET request or when anyerrors are encountered. The successView is the logical name of a view to display whenthe form has been submitted successfully. A view resolver use these values to locate the View object thatrenders the output to the user.
  34. 34. Input Validation The org.springframework.validation.Validator interfaceaccommodates validation for Spring MVC. public interface Validator { void validate(Object obj, Errors errors); boolean supports(Class clazz); } The validate() method examines fields of the object andreject invalid values via Error object (usingValidationUtils.rejectIfEmpty() method). The supports() method is used to help Spring determinewhether the validator can be used for a given class.
  35. 35. Commons Validator It enables to declare validation rules outside of Javacode. Spring uses the validation module (which uses JakartaCommons Validator) in Spring Modules project asimplementation for declarative validation. The validation module can be used in the applicationby making the springmodules-validator.jar fileavailable in the application’s classpath. Spring Modules provides an implementation ofValidator called DefaultBeanValidator.
  36. 36. DefaultBeanValidator DefaultBeanValidator delegates to Commons Validator tovalidate field values instead of doing any actual validation. DefaultBeanValidator has a validatorFactory property which iswired with a reference to a validatorFactory bean. The validatorFactory bean is declared as follows: <bean id="validatorFactory" class= "org.springmodules.commons.validator.DefaultValidatorFactory"> <property name="validationConfigLocations"> <list> <value>WEB-INF/validator-rules.xml</value> <value>WEB-INF/validation.xml</value> </list> </property> </bean>
  37. 37. DefaultBeanValidator DefaultValidatorFactory is a class that loads theCommons Validator configuration on behalf ofDefaultBeanValidator. The validationConfigLocations property takes a list ofone or more validation configurations. The validator-rules.xml file contains a set ofpredefined validation rules for common validationand comes with the Commons Validator distribution. The validation.xml, defines application-specificvalidation rules that apply directly to the sampleapplication.
  38. 38. Validation Declaration: Example <!DOCTYPE form-validation PUBLIC"-//DTDCommons Validator Rules Configuration1.1//EN“ "http://jakarta.apache.org/commons/dtds/validator_1_1.dtd"> <form-validation> <formset> <form name="rant"> <field property="rantText" depends="required"> <arg0 key="required.rantText" /> </field> <field property="vehicle.state" depends="required"> <arg0 key="required.state" /> </field> <field property="vehicle.plateNumber“ depends="required,mask"> <arg0 key="invalid.plateNumber" /> <var> <var-name>mask</var-name> <var-value>^[0-9A-Za-z]{2,6}$</var-value> </var> </field> </form> </formset> </form-validation>
  39. 39. AbstractWizardFormController A wizard form controller is a special type of formcontroller that collects form data from multiple pagesinto a single command object for processing
  40. 40.  public class MotoristRegistrationController extendsAbstractWizardFormController { public MotoristRegistrationController() { Sets command and class name } protected Object formBackingObject(HttpServletRequest request) throwsException { Motorist formMotorist = new Motorist(); List<Vehicle> vehicles = new ArrayList<Vehicle>(); vehicles.add(new Vehicle()); formMotorist.setVehicles(vehicles); return formMotorist; } protected Map referenceData(HttpServletRequest request, Object command, Errors errors, int page) throws Exception { Motorist motorist = (motorist) command; Map refData = new HashMap(); // Increments next vehicle pointer if(page == 1 && request.getParameter("_target1") != null) { refData.put("nextVehicle", motorist.getVehicles().size() - 1); } return refData; }
  41. 41.  protected void postProcessPage(HttpServletRequest request, Object command, Errors errors, int page) throws Exception { Motorist motorist = (Motorist) command; if(page == 1 && request.getParameter("_target1") != null) { motorist.getVehicles().add(new Vehicle()); // Adds new blank vehicle } } protected ModelAndView processFinish(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { Motorist motorist = (motorist) command; // the last vehicle is always blank...remove it motorist.getVehicles().remove(motorist.getVehicles().size() - 1); rantService.addMotorist(motorist); // Adds motorist return new ModelAndView(getSuccessView(), "motorist", motorist); } // returns the last page as the success view private String getSuccessView() { return getPages()[getPages().length-1]; } // injected RantService
  42. 42. MotoristRegistrationController The formBackingObject() method is overridden to set thevehicles property with a list of Vehicle objects as themotorist can also register for one or more vehicles. The list is also started with a blank Vehicle object for theform to populate. The referenceData() is overridden to make the index of thenext vehicle available to the form. The processFinish() method which is a mandatory methodis called to finalize the form when the user has finishedcompleting it. The processFinish() method sends the data in the Motoristobject to addMotorist() on the injected RantService object.
  43. 43. WizardFormController Configuration <bean id="registerMotoristController" class="com.roadrantz.mvc.MotoristRegistrationController"> <property name="rantService" ref="rantService" /> <property name="pages"> <list> <value>motoristDetailForm</value> <value>motoristVehicleForm</value> <value>motoristConfirmation</value> <value>redirect:home.htm</value> </list> </property> </bean> A list of logical view names is given to the pages property. Thesenames will ultimately be resolved into a View object by a viewresolver.
  44. 44. WizardFormController Configuration The first page to be shown in any wizard controller will be thefirst page in the list given to the pages property. To determine which page to go to next,AbstractWizardFormController consults its getTargetPage()method which returns an index into the zero-based list of pagesgiven to the pages property. The default implementation of getTargetPage() determineswhich page to go to next based on a parameter in the requestwhose name begins with _target and ends with a number (i.e.index into the pages list). Another special request parameter called _finish indicates to AbstractWizardFormController that the user has finished fillingout the form and wants to submit the information for processing.
  45. 45. Wizard Controller Cancellation A cancel button has _cancel as its name so that, which whenpassed to the AbstractWizardFormController as the parameter, itpasses the control to the processCancel() method. By default, processCancel() throws an exception indicating thatthe cancel operation is not supported, hence it must beoverridden. protected ModelAndView processCancel(HttpServletRequestrequest, HttpServletResponse response, Object command, BindException bindException) throws Exception { return new ModelAndView(getSucessView()); }
  46. 46. Validating the Wizard Wizard controllers validate the command object a page at a time,instead of validating the command object all at once. Every time when a page transition occurs the validatePage()method is called. The default implementation of validatePage() is empty (i.e., novalidation), which can be overridden. protected void validatePage(Object command, Errors errors, intpage) { Motorist motorist = (Motorist) command; MotoristValidator validator = (MotoristValidator) getValidator(); if(page == 0) { validator.validateEmail(motorist.getEmail(), errors); } }
  47. 47. Validating the Wizard <bean id="registerMotoristController" class="com.roadrantz.mvc.MotoristRegistrationController"> <property name="rantService" ref="rantService" /> <property name="pages"> <list> <value>motoristDetailForm</value> <value>motoristVehicleForm</value> <value>motoristConfirmation</value> <value>redirect:home.htm</value> </list> </property> <property name="validator"> <bean class="com.roadrantz.mvc.MotoristValidator" /> </property> </bean> Wizard controllers never call the standard validate() method of their Validatorobject, as validate() method validates the entire command object as a whole,whereas it is understood that the command objects in a wizard will bevalidated a page at a time.
  48. 48. Throwaway Controller public interface ThrowawayController { ModelAndView execute() throws Exception; } Throwaway controllers act as their own commandobject instead of giving HttpServletRequest andcommand object parameters.
  49. 49. Throwaway Controller public class RantsForDayController implements ThrowawayController { private Date day; public ModelAndView execute() throws Exception { List<Rant> dayRants = rantService.getRantsForDay(day); return new ModelAndView("dayRants", "rants", dayRants); } public void setDay(Date day) { this.day = day; } private RantService rantService; public void setRantService(RantService rantService) { this.rantService = rantService; } }
  50. 50. Throwaway Controller <bean id="rantsForDayController" class="com.roadrantz.mvc.RantsForDayController" scope="prototype"> <property name="rantService" ref="rantService" /> </bean> Before RantsForDayController handles the request, Spring calls thesetDay() method, passing in the value of the day request parameterbefore RantsForDayController handles the request. Once in the execute() method, RantsForDayController simply passesday to rantService and getRantsForDay() retrieves the list of rants forthat day. One thing that remains the same as the other controllers is that theexecute() method must return a ModelAndView object when it hasfinished. The scope attribute of the Throwaway Controller is set to prototype, asit is recycled between requests and should not be singleton by default. Also its properties (which should reflect the request parameter values)may also be reused. Setting scope to prototype tells Spring to throw thecontroller away after it has been used and to instantiate a fresh instancefor each request.
  51. 51. Throwaway Controller DispatcherServlet knows how to dispatch requests to controllersin the Controller interface hierarchy by using a default handleradapter. ThrowawayController isn’t in the same hierarchy as Controller,hence DispatcherServlet needs to use a different handler adapter. Specifically, you must configureThrowawayControllerHandlerAdapter as follows: <bean id="throwawayHandler"class="org.springframework.web.servlet.mvc.throwaway.ThrowawayControllerHandlerAdapter"/> Declaring the throwawayHandler bean, lets DispatcherServlet toreplace its default handler adapter withThrowawayControllerHandlerAdapter.
  52. 52. Throwaway Controller If the application uses both throwaway and regularcontrollers alongside each other then bothSimpleControllerHandlerAdapter andThrowawayControllerHandlerAdapter should bedeclared. <bean id="simpleHandler"class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
  53. 53. Handling exceptions SimpleMappingExceptionResolver handles exceptionsthrown from the controller. SimpleMappingExceptionResolver is configured as followsto handle any java.lang.Exceptions thrown from SpringMVC controllers: <bean id="exceptionResolver"class="org.springframework.web.servlet.handler. SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.Exception">friendlyError</prop> </props> </property> </bean>
  54. 54. Handling exceptions The exceptionMappings property takes ajava.util.Properties that contains a mapping of fullyqualified exception class names to logical view names. The base Exception class is mapped to the View whoselogical name is friendlyError so that if any errors arethrown, users won’t have to see an ugly stack trace butthe Friendly Error message in the friendlyError view. When a controller throws an Exception,SimpleMappingExceptionResolver resolves it tofriendlyError, which in turn resolves to a View usingthe configured view resolver(s).

×