Spring 3 MVC Basics

Sang Shin javapassion.com “Learn with Passion!”

• Introduction to Spring MVC
> DispatchServlet, Context configuration

• Controller
> Annotation-based controllers, Request mapping, URI

template, request mapping with other means, Handler method arguments, Handler methods return types

• Handler mapping customization
> Interceptor

• Resolving views
> Spring-provided view resolvers, Chaining view


• Spring 3 <mvc:.. > configuration


Spring Framework Codecamp
• This topic is one of many topics that are covered in Spring Framework codecamp
> javapassion.com/codecamps

• Spring framework topics
> Spring DI basics, Spring DI advanced, Spring DI > > > > > >

annotation Spring MVC basics, form handling, Ajax, REST, Views Spring Webflow Spring database access (JDBC, Hibernate, JPA), transaction Spring AOP, Spring security, Spring testing Spring JMS, Spring JMX Spring Roo


What is Spring MVC? • MVC-based Web application framework that takes advantage of design principles of Spring framework > Dependency Injection > Interface-driven design > POJO style everywhere 4 .

Features Spring Web MVC Framework 5 .

and so on -. and more) for a given scenario 6 . handler mapping.can be fulfilled by a specialized object and replaceable without affecting others • Powerful and straightforward configuration of both framework and application classes as JavaBeans • Adaptability. @RequestHeader. form object. @PathVariable. command object. validator.Features of Spring Web MVC • Clear separation of roles > Controller. view resolver. model object. non-intrusiveness. DispatcherServlet. possibly using one of the parameter annotations (such as @RequestParam. and flexibility > Define any controller method signature you need.

Features of Spring Web MVC (Continued) • Customizable binding (conversion) and validation • Customizable handler mapping and view resolution > Handler mapping and view resolution strategies range from simple URL-based configuration. purpose-built resolution strategies. • Flexible model transfer > Model transfer with a name/value Map supports easy integration with any view technology • Customizable locale and theme resolution • A simple yet powerful JSP tag library known as the Spring tag library 7 . to sophisticated.

DispatcherServlet 8 .

xml 9 .DispatcherServlet • It plays the role of Front controller in Spring MVC > Coordinates the HTTP request life-cycle > Configured in web.

Sequence of HTTP Request Handling
1. DispatchServlet receives a HTTP request 2. DispatchServlet selects a Controller based on the URL Handler mapping and pass the request to the Controller 3. Controller (actually handler in a Controller) performs the business logic and set values of Model objects 4. Controller returns a logical view 5. A ViewResolver, which provides a particular view (JSP, PDF, Excel, etc.), is selected 6. A view gets displayed using values of Model objects

DispatcherServlet Configuration
• Configured in the “web.xml” file as a regular servlet
<web-app> <servlet> <servlet-name>example</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> 11

Spring Context Configuration


Typical Configuration Setup • Two Spring bean containers (or ApplicationContexts) initialized .not mandatory > 1 “root” context to host “shared resources” required by servlets/filters/services > 1 “web” context to host local application components delegated by the DispatchServlet 13 .

xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> Web context 14 .org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.com/xml/ns/javaee/web-app_2_5.web.com/xml/ns/javaee http://java.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.xml</param-value> </context-param> Root context <!-.Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.sun.sun.context.The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.springframework.5" xmlns="http://java.ContextLoaderListener</listener-class> </listener> <!-.web.com/xml/ns/javaee" xmlns:xsi="http://www.w3.xsd"> <!-.sun.servlet.Example: web.0" encoding="UTF-8"?> <web-app version="2.springframework.xml <?xml version="1.

15 .

Default Location/Name of Web Context File • The location and name of the Web context file is typically configured with DispatcherServlet > As you've seen in the previous slide • If it is not configured.Spring will search for /WEB-INF/appServlet-servlet.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> 16 .springframework.xml • Example <!-. Spring searches the default web context file > /WEB-INF/[servlet-name]-servlet.web.xml --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class> org.

WebApplicationContext File
• Spring MVC beans that can be defined in the WebApplicationContext file include
> > > > > > >

Controllers Handler mappings View resolvers Locale resolvers Theme resolvers Multipart file resolver Hanlder exception resolvers


Spring MVC Interfaces


Spring MVC Interfaces
• Key features of the Spring MVC are modularized through Spring MVC interfaces
> Custom implementations can be created and

configured > This is how Spring framework itself can be extended and customized

• Spring framework comes with built-in implementations of the interfaces
> Default implementation is pre-selected for most

common cases


20 . but more flexible • LocaleResolver cookie > Selects locale based on HTTP accept header.Spring MVC Interfaces • HandlerMapping > Routing of requests to handlers (controllers) • ViewResolver > Maps symbolic name to view • HandlerExceptionResolver > Maps exceptions to error pages > Similar to standard Servlet.

Controllers 21 .

What does a Controller do? • Controllers provide access to the business logic > Typically a controller delegates business logic processing to a set of services > The services in turn access database through Dao interface • Controllers interpret user input and transform it into a model and set attributes (key/value pairs) of the model as a result of business logic 22 .

Controllers: Annotation-based Controllers 23 .

etc > Your controller code is tied up with framework . you had to extend Springspecific base controller classes > SimpleFormController. MultiActionController. > Annotation-based controllers do not usually have direct dependencies on Servlet or Portlet APIs either > Annotation-based controllers are POJO's 24 .Annotation-based Controllers • In pre-Spring 2.they are not POJO's • Spring 2.5.5 introduced an annotation-based controllers > Annotation-based controllers do not have to extend specific base controller classes or implement specific interfaces.

@Controller public class HelloWorldController { // There is no constraint to the method signature either @RequestMapping("/helloWorld") public ModelAndView helloWorld() { ModelAndView mav = new ModelAndView().addObject("message".Annotation-based Controller // Annotation-based Controller do not have // to extend specific Spring base classes or implement // specific interfaces. "Hello World!"). mav. return mav. } 25 } . // set the view mav.setViewName("helloWorld").

springframework.org/schema/context http://www.springframework.springframework.org/schema/beans http://www.org/2001/XMLSchema-instance" xmlns:p="http://www.org/schema/context" xsi:schemaLocation=" http://www.0.samples.springframework.. </beans> 26 .springframework..there is no need to declare them in the context configuration file <?xml version="1.org/schema/beans/spring-beans-3.w3.Auto-detection of Annotated Controllers • Through component scanning.petclinic.org/schema/context/spring-context-3.springframework.xsd http://www.org/schema/beans" xmlns:xsi="http://www.springframework.org/schema/p" xmlns:context="http://www.0" encoding="UTF-8"?> <beans xmlns="http://www.0.springframework.web"/> // . all annotated controller beans are automatically detected .xsd"> <context:component-scan base-package="org.

Controllers: Mapping Requests to Handlers with @RequestMapping 27 .

Mapping requests with @RequestMapping • @RequestMapping annotation is used to map URLs such as /appointments onto a class (when used over a class) or a particular handler method (when used over a method) 28 .

@Autowired public AppointmentsController(AppointmentBook appointmentBook) { this.GET) public Map<String. } // Handle http://locahost:8080/myapp/appointments @RequestMapping(method = RequestMethod.getAppointmentsForDay(day). Appointment> get() { return appointmentBook. } // Handle http://locahost:8080/myapp/appointments/4 or // http://locahost:8080/myapp/appointments/5 @RequestMapping(value="/{day}".Mapping requests with @RequestMapping @Controller @RequestMapping("/appointments") public class AppointmentsController { private final AppointmentBook appointmentBook. 29 } .GET) public Map<String.appointmentBook = appointmentBook.getAppointmentsForToday(). Model model) { return appointmentBook. Appointment> getForDay ( @PathVariable @DateTimeFormat(iso=ISO.DATE) Date day. method = RequestMethod.

addAppointment(appointment). } } We will cover “form handling” in detail in another presentation and hands-on lab .“spring3_mvc_form”. 30 . method = RequestMethod. method = RequestMethod.hasErrors()) { return "appointments/new". return "redirect:/appointments".@RequestMapping for Form Handling // Continued from previous slide // Handles http://locahost:8080/myapp/appointments/new // Display initial form @RequestMapping(value="/new". } appointmentBook.GET) public AppointmentForm getNewForm() { return new AppointmentForm(). } // Handles http://locahost:8080/myapp/appointments/new // Handle form submission @RequestMapping(value="/new".POST) public String add(@Valid AppointmentForm appointment. BindingResult result) { if (result.

@RequestMapping Only at Method Levels // A @RequestMapping on the class level is not required. @Autowired public ClinicController(Clinic clinic) { this. Without it. } // Handles http://locahost:8080/myapp/ @RequestMapping("/") public void welcomeHandler() { } // Handles http://locahost:8080/myapp/vets @RequestMapping("/vets") public ModelMap vetsHandler() { return new ModelMap(this. } } 31 . all paths // are simply absolute. @Controller public class ClinicController { private final Clinic clinic.clinic.clinic = clinic. and not relative.getVets()).

Controllers: URI Template 32 .

/owners/3 /owners/5 • The request URI is compared to an matching URI Template 33 . containing one or more variable names > Variables are in the form of {nameOfVariable} @RequestMapping(value="/owners/{ownerId}")) • When you substitute values for these variables.What is URI Template? • A URI Template is a URI-like string. the template becomes a concrete URI.

Model model) { Owner owner = ownerService.addAttribute("owner". return "displayOwner".URI Template Example #1 // Suppose the request URL is http://locahost:8080/myapp/owners/3. method=RequestMethod.GET) public String findOwner(@PathVariable String ownerId. model. } 34 .findOwner(ownerId). // the value 3 will be captured as “ownerId” argument in String type. @RequestMapping(value="/owners/{ownerId}". owner).

URI Template Example #2 // You can use multiple @PathVariable annotations to bind to multiple URI // Template variables. return "displayPet". model.getPet(petId).findOwner(ownderId). // Suppose the request URL is http://locahost:8080/myapp/owners/3/pets/5.GET) public String findPet(@PathVariable String ownerId. pet). // the value 3 will be captured as “ownerId” argument in String type while // the value 5 will be captured as “petId” argument in String type. Model model) { Owner owner = ownerService. method=RequestMethod. Pet pet = owner. } 35 . @PathVariable String petId.addAttribute("pet". @RequestMapping(value="/owners/{ownerId}/pets/{petId}".

Model model) { // implementation omitted } } 36 .URI Template Example #3 // You can use multiple @PathVariable annotations to bind to multiple URI // Template variables @Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @RequestMapping("/pets/{petId}") public void findPet(@PathVariable String ownerId. @PathVariable String petId.

Controllers: Mapping Requests with Other Means 37 .

Mappings through parameter conditions // You can narrow path mappings through parameter conditions: a sequence of // "myParam=myValue" style expressions. params="myParam=myValue") public void findPet(@PathVariable String ownerId. @Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { // Handles http://locahost:8080/myapp/owners/3/pets/5?myParam=myValue @RequestMapping(value = "/pets/{petId}". with a request only mapped if each // such parameter is found to have the given value. Model model) { // implementation omitted } } 38 . @PathVariable String petId.

headers="content-type=text/*") public void addPet(Pet pet.POST. method = RequestMethod. text/xml @Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @RequestMapping(value = "/pets".Mappings through HTTP header conditions // The addPet() method is only invoked when the content-type matches the // text/* pattern. @PathVariable String ownerId) { // implementation omitted } } 39 . for example.

Controllers: Handler Method Arguments 40 .

Objects that are auto-created by Spring • You can simply use these as handler arguments • Request or response objects (Servlet API) > ServletRequest or HttpServletRequest • Session object (Servlet API) > HttpSession • java.Locale > For the current request locale.util.security.Principal > Currently authenticated user 41 . determined by the most specific locale resolver available • java.

@PathVariable & @RequestParam • @PathVariable > Annotated parameters for access to URI template variables > Extracts data from the request URI > http://host/catalog/items/123 > Parameter values are converted to the declared method argument type • @RequestParam(“namex”) > Annotated parameters for access to specific Servlet request parameters. > Extracts data from the request URI query parameters > http://host/catalog/items/?namex=abc > Parameter values are converted to the declared method argument type 42 .

. 43 .@PathVariable ./pets/10 @RequestMapping(method = RequestMethod.addAttribute("pet".For URI Path Values // Use the @PathVariable annotation to bind URI path value to a method // parameter in your controller.GET) public String getData(@PathVariable int petId.. ModelMap model) { Pet pet = this.. } // .../pets/4 or . pet). return "petForm".loadPet(petId). model. // Will handle .clinic.. @Controller @RequestMapping("/pets") public class MyPetClass { // .

.GET) public String getData(@RequestParam("petId") int petId.. pet).. 44 ./pets?petId=4 or .loadPet(petId). @Controller @RequestMapping("/pets") public class MyPetClass { // .addAttribute("pet"..@RequestParam . ModelMap model) { Pet pet = this.clinic. return "petForm". } // ./pets?petId=10 @RequestMapping(method = RequestMethod.For Query Parameters // Use the @RequestParam annotation to bind query request parameters to a // method parameter in your controller. model. // Will handle ...

> Parameter values are converted to the declared method argument type using HttpMessageConverter's 45 .Request Header and Body • @RequestHeader(“name”) > Annotated parameters for access to specific Servlet request HTTP headers • @RequestBody > Annotated parameters for access to the HTTP request body.

Writer writer) throws IOException { writer.write(body). } 46 . @RequestMapping(value = "/something". method = RequestMethod.PUT) public void handle(@RequestBody String body.@RequestBody // The @RequestBody method parameter annotation indicates that a method // parameter should be bound to the value of the HTTP request body.

Implicit Models 47 .Controllers: Handler Method Arguments .

Implicit Models as Handler Arguments • These are exposed to the view > View can access these models after attributes of these models are set in the handler methods • Model types that are allowed > java. 48 .util.ui.Map > org.ui.Model > Holder of attributes > org.springframework.ModelMap > Supports chained calls and auto-generation of model attribute names.springframework.

The view now can access // “hotelList” through ${hotelList} notation model.Model object as Handler argument @RequestMapping(value = "/hotels-search". method = RequestMethod. perform the search through // "bookingService". // Add an attribute to the model.jsp". } 49 . List<Hotel> hotels = bookingService. which results in displaying // "hotels/list. hotels).addAttribute(“hotelList”.findHotels(criteria). // Return logical view name "hotels/list". return "hotels/list".GET) public String list(SearchCriteria criteria. Model model) { // Using the "SearchCriteria".

State</th> <th>Zip</th> <th>Action</th> </tr> </thead> <tbody> <c:forEach var="hotel" items="${hotelList}"> <tr> <td>${hotel.city}. ${hotel. ${hotel.state}.country}</td> <td>${hotel.View that accesses the Model <table class="summary"> <thead> <tr> <th>Name</th> <th>Address</th> <th>City.zip}</td> <td><a href="hotels/${hotel.name}</td> <td>${hotel.id}">View Hotel</a></td> </tr> </c:forEach> <c:if test="${empty hotelList}"> <tr> <td colspan="5">No hotels found</td> </tr> </c:if> </tbody> </table> 50 .address}</td> <td>${hotel.

accountNo) .addAttribute("balance". ModelMap modelMap) { accountService. @RequestParam("amount") double amount. return "success".do") protected String deposit( @RequestParam("accountNo") int accountNo.deposit(accountNo. // Chaining is allowed for ModelMap object modelMap.getBalance(accountNo)). amount). accountService. } 51 .addAttribute("accountNo".ModelMap object as Handler argument @RequestMapping("/deposit.

Controllers: HttpMessageConverters 52 .

HttpMessageConverter's • Behind the scene. the first converter that can read the POSTed “Content-Type” into the desired method parameter type is used • For @ResponseBody. a HttpMessageConverter is involved for reading request body and generating response body • Different converters are registered for different content types • For @RequestBody. the first converter that can write the method return type into one of the client's “Accept”'ed content type is used • Default set of HttpMessageConverters are registered for you 53 .

String> (for request) > Writes MultiValueMap<String. String> into “application/x-www-form-urlencoded” (for response) • ByteArrayMessageConverter > Reads “*/*” into a byte[] > writes Objects as “application/octet-stream” 54 .Default HttpMessageConverters • StringHttpMessageConverter > Reads “text/*” into Strings (for request) > Writes Strings as “text/plain” (for response) • FormHttpMessageConverter > Reads “application/x-www-form-urlencoded” into MultiValueMap<String.

Controllers: Handler Method Return Types 55 .

//logical view name mav. // and again ma! } return mav. 56 .addObject(cartItems). HttpServletResponse response) { List cartItems = // get a List of CartItem objects User user = // get the User doing the shopping ModelAndView mav = new ModelAndView("displayShoppingCart"). just the object mav. no name.ModelAndView Object public class DisplayShoppingCartController implements Controller { public ModelAndView handleRequest(HttpServletRequest request.addObject(user). // look ma.

Most Popular) • Is interpreted as the logical view name.addAttribute("fruit". method=RequestMethod. return "views/html". with the model implicitly determined through command objects and @ModelAttribute annotated reference data accessor methods // Logical view is returned as “view/html” @RequestMapping(value="html". "apple"). model.addAttribute("foo". "bar").String (Logical View Name . } 57 .GET) public String prepare(Model model) { model.

} 58 .addAttribute("foo". method=RequestMethod. "bar").GET) public void usingRequestToViewNameTranslator(Model model) { model. "apple").addAttribute("fruit".void • Used in two situations > #1: when the method handles the response itself (by writing the response content directly. declaring an argument of type ServletResponse / HttpServletResponse for that purpose) > #2: When the view name is supposed to be implicitly determined through a RequestToViewNameTranslator // #2: The view name is implicitly set to “viewNameX” @RequestMapping(value="/viewNameX". model.

@ResponseBody annotated Method • If the method is annotated with @ResponseBody. the return type is written to the response HTTP body @RequestMapping(value="/response/annotation".GET) public @ResponseBody String responseBody() { return "The String ResponseBody". } 59 . method=RequestMethod.

A HttpEntity<?> or ResponseEntity<?> • Provide access to the Servlet reponse HTTP headers and contents. method=RequestMethod. HttpStatus. headers.GET) public ResponseEntity<String> responseEntityCustomHeaders() { HttpHeaders headers = new HttpHeaders().OK).TEXT_PLAIN).setContentType(MediaType. return new ResponseEntity<String>("The String ResponseBody with custom header Content-Type=text/plain". } 60 . • The entity body will be converted to the response stream using HttpMessageConverter @RequestMapping(value="/response/entity/headers". headers.

Controllers: @SessionAttributes 61 .

@SessionAttributes • Declares session attributes used by a specific handler. serving as formbacking beans between subsequent requests. 62 . • This will typically list the names of model attributes or types of model attributes which should be transparently stored in the session or some conversational storage.

. } 63 .@SessionAttributes @Controller @RequestMapping("/editPet.do") @SessionAttributes("pet") public class EditPetForm { // ..

Handler Mapping Customization 64 .

users were required to define HandlerMappings in the web application context to map incoming web requests to appropriate handlers. you do not need to override this default mapping.DefaultAnnotationHandlerMapping • In pre-2.5 versions of Spring. unless you need to override the default property values for customization 65 . • From Spring 2. the DispatcherServlet enables the DefaultAnnotationHandlerMapping as a default > DefaultAnnotationHandlerMapping searches for @RequestMapping annotations on @Controllers > Typically.5.

Handler Mapping Properties • interceptors • defaultHandler > Default handler to use. • order 66 . when this handler mapping does not result in a matching handler.

Handler Mappings: Interceptor 67 .

DefaultAnnotationHandle rMapping"> <property name="interceptors"> <bean class="example.mvc.annotation.MyInterceptor"/> </property> </bean> <beans> 68 .web.Add an “interceptor” to default mapping // This example shows how to override the default mapping and add an // interceptor: <beans> <bean id="handlerMapping" class="org.springframework.servlet.

When this method returns true.) method .. the handler execution chain will continue. logging.What Do Interceptors Do? • Interceptors are useful when you want to apply specific functionality to certain requests > Authentication. when it returns false. etc • Interceptors must implement HandlerInterceptor interface > boolean preHandler(. for example. authorization. the DispatcherServlet assumes the interceptor itself has taken care of requests (and. rendered an appropriate view) and does not continue executing the other interceptors and the actual handler in the execution chain > void postHandler(..) method 69 .

getLogger(LoggingInterceptor. } public void postHandle(HttpServletRequest request. } } 70 . Object handler) throws Exception { logger. return true.info("LoggingInterceptor: preHandle() entered").Java Code public class LoggingInterceptor extends HandlerInterceptorAdapter { private static final Logger logger = LoggerFactory.info("LoggingInterceptor: postHandle() exiting"). ModelAndView modelAndView) throws Exception { logger. HttpServletResponse response. HttpServletResponse response.Interceptor Example #1 . Object handler.class). public boolean preHandle(HttpServletRequest request.

springframework.Interceptors are applied to all annotated controllers --> <property name="interceptors"> <list> <ref bean="elapsedTimeInterceptor" /> <ref bean="loggingInterceptor" /> </list> </property> </bean> 71 .examples.DefaultAnnotationHandle rMapping"> <property name="order" value="1" /> <!-.Configuration <!-.servlet.ElapsedTimeInterceptor" /> <bean id="loggingInterceptor" class="com.examples.Interceptor Example #1 .LoggingInterceptor" /> <!-.javapassion.mvc.Annotation handlers (Applied by default to ALL @controllers --> <bean class="org.javapassion.web.annotation.Interceptors --> <bean id="elapsedTimeInterceptor" class="com.

return false.com/outsideOfficeHours. } else { response. public boolean preHandle( HttpServletRequest request.get(HOUR_OF_DAY).sendRedirect("http://host. public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { . HttpServletResponse response.getInstance(). int hour = cal..html"). if (openingTime <= hour < closingTime) { return true. Object handler) throws Exception { Calendar cal = Calendar.. } } } 72 .Interceptor Example #2 package samples.

TimeBasedAccessInterceptor"> <property name="openingTime" value="9"/> <property name="closingTime" value="18"/> </bean> <beans> 73 .view=editAccountFormController </value> </property> </bean> <bean id="officeHoursInterceptor" class="samples.web.handler.form=editAccountFormController /*.Configuration <beans> <bean id="handlerMapping" class="org.servlet.Interceptor Example #2 .SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="officeHoursInterceptor"/> </list> </property> <property name="mappings"> <value> /*.springframework.

Views vs. @ResponseBody 74 .

XML.Two Schemes of Rendering Response • Two schemes for rendering response > ViewResolver + View > HttpMessageConverter • They are triggered in different ways > Render a view by returning a logical view String > Write a message by returning a @ResponseBody or ResponseEntity • Which one to use? > Use ViewResolver + View to generate documents for display in a web browser .HTML. etc > Use @ResponseBody to exchange data with web service clients .JSON. etc 75 . PDF.

Resolving Views 76 .

View. based on conventions) • Views in Spring are addressed by a logical view name and are resolved by a view resolver • Spring comes with quite a few view resolvers 77 .Resolving Views • All handler methods in the Spring Web MVC controllers must resolve to a logical view name > Explicitly (e.g. or ModelAndView) or > Implicitly (i.. by returning a String..e.

Resolving Views: Spring-Provided ViewResolvers 78 .

View Resolvers • UrlBasedViewResolver • InternalResourceViewResolver > It is a subclass of UrlBasedViewResolver • • • • ResourceBundleViewResolver AbstractCachingViewResolver XmlViewResolver ContentNegotiatingViewResolver 79 .

springframework.jsp"/> </bean> 80 .view.servlet.springframework. <bean id="viewResolver" class="org.view. without the need for // arbitrary mappings. This is appropriate if your symbolic names match the names of // your view resources in a straightforward manner.web.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".UrlBasedViewResolver // A simple implementation of the ViewResolver interface that effects the direct // resolution of symbolic view names to URLs.web.jsp.UrlBasedViewResolver"> <property name="viewClass" value="org. without an explicit mapping // definition. this view resolver forwards // the request to the RequestDispatcher that will send the request to // /WEB-INF/jsp/test. // When returning test as a logical view name.servlet.

view. and subclasses such // as JstlView and TilesView.web.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> 81 .InternalResourceViewResolver // A convenience subclass of UrlBasedViewResolver that supports // InternalResourceView (i. <bean class="org. Servlets and JSPs).e.servlet.springframework.

views.servlet.springframework.view.ResourceBundleViewResolver"> <property name="basename" value="views"/> <property name="defaultParentView" value="parentView"/> </bean> resource bundle # views.springframework.RedirectView welcomeRedirect.servlet.examples.web.(class)=com.jsp reservationSuccessRedirect.view. <bean id="viewResolver" class="org. (class)=org. it uses the value // of the property [viewname].jsp reservationSummary.view.url=reservationSuccess. and for each view it is supposed to resolve.(class)=org.servlet.RedirectView reservationSuccessRedirect.springframework.web.ExcelReservation 82 .ResourceBundleViewResolver // The ResourceBundleViewResolver inspects the ResourceBundle identified // by the basename.url=welcome.web.url as the view url.properties file in the classpath welcomeRedirect.javapassion.(class) as the view class and the value of the // property [viewname].

Resolving Views: Chaining ViewResolvers 83 .

by setting the order property to specify ordering. the later the view resolver is positioned in the chain > InternalResourceViewResolver is automatically positioned as the last ViewResolver • If a specific view resolver does not result in a view. > The higher the order property. Spring continues to inspect them until a view is resolved 84 .Chaining ViewResolver's • You chain view resolvers by adding more than one resolver to your application context and. if necessary.

the chain of view resolvers consists of two resolvers.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".web. <bean id="excelViewResolver" class="org.web.springframework.XmlViewResolver"> <property name="order" value="1"/> <property name="location" value="/WEB-INF/views.view.view. and an XmlViewResolver for specifying Excel // views. // an InternalResourceViewResolver.servlet. which is always automatically positioned as // the last resolver in the chain. Excel views are not supported by the InternalResourceViewResolver.servlet.jsp"/> </bean> 85 .Chaining ViewResolver's // In the following example.xml"/> </bean> <bean id="jspViewResolver" class="org.springframework.

Type Conversion 86 .

@ResponseBody. JavaBean. Date. HttpEntity. @DateTimeFormat 87 . Map • Can declare annotation-based conversion rules > @NumberFormat. ResponseEntity • All major conversion occur out of the box > Primitive. String. Collection. @CookieValue • HttpMessageConverter used for > @RequestBody.Type Conversion • Type conversion happens automatically • A common “ConversionService” used in the places where type conversion is required > @RequestParam. @PathVariable > @RequestHeader.

Convention over Configuration Support: Automatic Key name Generation in ModelMap ModeAndView 88 .

89 .ModelMap & ModelAndView Classes • The ModelMap class is essentially a glorified Map that can make adding objects that are to be displayed in (or on) a View adhere to a common naming convention • The ModelAndView class uses a ModelMap class that is a custom Map implementation that automatically generates a key for an object when an object is added to it.

// “cartList” is automatically generated as a key mav.addObject(user).addObject(cartItems). HttpServletResponse response) { List cartItems = // get a List of CartItem objects User user = // get the User doing the shopping // “displayShoppingCart” is logical view ModelAndView mav = new ModelAndView("displayShoppingCart").Automatic Key Generation for ModelAndView public class DisplayShoppingCartController implements Controller { public ModelAndView handleRequest(HttpServletRequest request. mav. //”user” is automatically generated as a key } return mav. } 90 .

User elements added will have the name fooList > A java.use the short class name of the object's class > x.y.y.Foo[] array with one or more x.y.y.y.User[] array with one or more x.y.y.User elements added will have the name userList > An x.Key Name Generation Strategy • Scalar object .util.Registration instance added will have the name registration • Collection object > An x.User elements added will have the name userList 91 .User instance added will have the name user > x.ArrayList with one or more x.

Convention over Configuration Support: Logical View Name Generation 92 .

. ModelAndView mav = new ModelAndView().Handler Without Setting Logical View // A request URL of http://localhost/registration. This logical view name is then // resolved into the /WEB-INF/jsp/registration. // notice that no View or logical view name has been set } } 93 .html results in a logical view // name of registration being generated by the // DefaultRequestToViewNameTranslator..jsp view by the // InternalResourceViewResolver bean... return mav. HttpServletResponse response) { // process the request. public class RegistrationController implements Controller { public ModelAndView handleRequest(HttpServletRequest request. // add data as necessary to the model.

servlet.view.maps request URLs to Controller names --> <bean class="org.support. It is configured here for demo purpose.web.springframework.servlet.This bean with the well known name generates view names for us.RegistrationController"> <!-. This gets automatically configured by Spring.springframework.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".view.Configuration for Logical View Name Generation (This is done for you) <beans> <!-.web.jsp"/> </bean> </beans> 94 .springframework.inject dependencies as necessary --> </bean> <!-.web.y.DefaultRequestToViewNameTranslator"/> <bean class="x.ControllerClassNameHandlerMapping"/ > <bean id="viewResolver" class="org.mvc.servlet. --> <bean id="viewNameTranslator" class="org.

> Configuration 95 ..Spring 3 <mvc: .

> Instead of registering low-level beans such as AnnotationMethodHandlerAdapter.Spring 3 Enhancement • Spring 3 introduces a mvc XML configuration namespace that simplifies the setup of Spring MVC inside your web application. you can simply use the namespace and its higher-level constructs. > This is generally preferred unless you require finergrained control of the configuration at the bean level. 96 .

> <mvc:interceptors . > <mvc:resources .> <mvc:default-servlet-handler .. > <mvc:view-controller ..> 97 ....Tags in <mvc: .> Namespace • • • • • <mvc:annotation-driven ..

• The tag configures those two beans with sensible defaults based on what is present in your classpath. 98 .<mvc:annotation-driven /> • This tag registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans that are required for Spring MVC to dispatch requests to @Controllers.

and Joda Time fields using the @DateTimeFormat annotation. 99 . Calendar.3 or higher is present on the classpath.<mvc:annotation-driven /> Defaults • Support for Spring 3's Type ConversionService in addition to JavaBeans PropertyEditors during Data Binding. Long. • Support for formatting Number fields using the @NumberFormat annotation • Support for formatting Date. if Joda Time 1.

if a JSR-303 Provider is present on the classpath. • Support for reading and writing XML • Support for reading and writing JSON 100 .<mvc-annotation-driven> Defaults • Support for validating @Controller inputs with @Valid. The validation system can be explicitly configured by setting the validator attribute.

org/schema/beans http://www.springframework.springframework.springframework.w3.0.org/schema/mvc http://www.0.org/schema/beans" xmlns:mvc="http://www.springframework.springframework.springframework.<mvc:annotation-driven/> Example <?xml version="1.xsd"> <!-.org/schema/mvc" xmlns:xsi="http://www.0" encoding="UTF-8"?> <beans xmlns="http://www.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.org/schema/mvc/spring-mvc-3.org/schema/beans/spring-beans-3.xsd http://www.JSR-303 support will be detected on classpath and enabled automatically--> <mvc:annotation-driven/> </beans> 101 .

html” immediately maps to “index” view --> <mvc:view-controller path="/index.The url “/” immediately maps to “welcome” view --> <mvc:view-controller path="/" view-name="welcome"/> <!-.<mvc:view-controller> • This tag is a shorcut for defining a ParameterizableViewController that immediately maps incoming request to a view • Use it in static cases when there is no Java Controller logic to execute before the view generates the response • Example <!-.The url “/index.html" view-name="index"/> 102 .

<mvc:resources> from 3. including locations on the classpath • The cache-period property may be used to set far future expiration headers • Example <!-.0.4 • Provides a convenient way to serve static resources from locations other than the web application root.Serve resource requests with a URL pattern of /resources/** from a public-resources directory --> <mvc:resources mapping="/resources/**" location="/public-resources/" cache-period="31556926"/> 103 .

<mvc:default-servlet-handler> from 3. while still allowing static resource requests to be handled by the container's default Servlet. • It configures a DefaultServletHttpRequestHandler with a URL mapping (given a lowest precedence order) of "/**".4 • Allows for mapping the DispatcherServlet to "/" (thus overriding the mapping of the container's default Servlet).0. • This handler will forward all requests to the default Servlet. • Example <mvc:default-servlet-handler/> 104 .

Example <mvc:default-servlet-handler/> <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/> <mvc:resources mapping="/style/**" location="/style/" cache-period="31556926"/> <mvc:resources mapping="/image/**" location="/image/" cache-period="31556926"/> 105 .

Logging 106 .

apache.Appenders --> <appender name="console" class="org.springframework.log4j.3rdparty Loggers --> <logger name="org.%m%n" /> </layout> </appender> <!-.beans"> <level value="info" /> </logger> <logger name="org.springframework.xml <log4j:configuration xmlns:log4j="http://jakarta.log4j.org/log4j/"> <!-.apache.springframework.log4j.core"> <level value="info" /> </logger> <logger name="org.web"> <level value="debug" /> </logger> <!-.context"> <level value="info" /> </logger> <logger name="org.out" /> <layout class="org.Root Logger --> <root> <priority value="warn" /> <appender-ref ref="console" /> </root> </log4j:configuration> 107 .ConsoleAppender"> <param name="Target" value="System.springframework.apache.PatternLayout"> <param name="ConversionPattern" value="%-5p: %c .

appender.MaxBackupIndex=3 # Pattern to output: date priority [category] .ConversionPattern=%d %p [%c] .File=${mvc_basics_form.org.xml to activate Log4J.%m%n log4j.log #log4j.apache.properties # For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.PatternLayout log4j.appender. stdout.root}/WEB-INF/mvc_basics_form.log4j.apache.layout.appender.ConversionPattern=%d %p [%c] .layout=org.springframework.PatternLayout #log4j.log4j.<%m>%n #log4j.message #log4j.appender.appender.rootLogger=INFO.apache.log4j.stdout.appender.xml! # For all other servers: Comment out the Log4J listener in web.layout=org. #log4j.appender.ConsoleAppender log4j.rootLogger=ERROR.stdout. #log4j.web=DEBUG 108 .logfile=org.apache.logfile.RollingFileAppender #log4j.log4j.log4j.layout.logfile. stdout log4j.appender.appender. logfile log4j.logfile.logger.logfile.logfile.stdout=org.MaxFileSize=512KB # Keep three backup files.

com Codecamps! http://www.com/codecamps “Learn with Passion!” 109 109 .javapassion.Thank you! Check JavaPassion.

Sign up to vote on this title
UsefulNot useful