Spring MVC - The Basics

1,939 views

Published on

An introduction to the basics of the Spring MVC Web framework. The concepts of front controller, controller (handler), model and view are introduced. The whole processing pipeline is discussed, with an in-depth description of the HandlerMapping and ViewResolver strategy interfaces. The alternative representations of the Model (Map, Model and ModelMap) are presented.

Published in: Education
2 Comments
17 Likes
Statistics
Notes
  • Hi Catalio, Can you please send me this Spring MVC The Basics document to me. at littleprince.rishi@gmail.com It will be really helpful. Thanks Rishiraj
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Hi Catalio,

    Can you please send me this Spring MVC The Basics document to me.

    at bose.rajib@yahoo.co.in

    It will be really helpful. Thanks.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
1,939
On SlideShare
0
From Embeds
0
Number of Embeds
103
Actions
Shares
0
Downloads
0
Comments
2
Likes
17
Embeds 0
No embeds

No notes for slide

Spring MVC - The Basics

  1. 1. Spring MVC - The Basics Ilio Catallo - info@iliocatallo.it
  2. 2. Outline • MVC and MVC 2 • Request processing pipeline • Se8ng up Spring MVC • Wri:ng Controllers • References
  3. 3. MVC and MVC 2
  4. 4. Model-View-Controller The Model-View-Controller (MVC) pa5en was invented at Xerox Parc by Trygve Reenskaug in 1979
  5. 5. MVC pa'ern Applica'ons should have three major parts • The part that manages the data • The part that creates screens and reports • The part that handles interac3ons between the user and the other subsystems
  6. 6. MVC pa'ern Applica'ons should have three major parts • Model • View • Controller
  7. 7. MVC pa'ern Applica'ons should have three major parts • Domain model • View • Controller
  8. 8. MVC pa'ern +------------------+ +---------------+ | | | Controller +----------+ | +-------> | | View | +------------------+ | selection | | | | | | | State change | User | | interaction | | | | +---v-------+---+ +-------v--------+ | | | | | View <---Change notification---+ Domain model | | | | | +-------+-------+ +-------^--------+ | | | | +---------------State query---------------+
  9. 9. What is the reason not to use the same MVC pa2ern also for Web applica7ons?
  10. 10. HTTP limita*ons The reason is that the HTTP protocol limits the applicability of the MVC pa7ern
  11. 11. Stateless protocol The MVC pa*ern requires a stateful protocol to keep track of the applica.on state
  12. 12. Applica'on state "If we think of an applica1on as being computerized behavior that achieves a goal, we can describe an applica1on protocol as the set of legal interac1ons necessary to realize that behavior. Applica3on state is a snapshot of an execu1on of such an applica1on protocol." (J. Webber et al.)
  13. 13. Stateless protocol However, HTTP is stateless
  14. 14. Pull protocol The MVC pa*ern requires a push protocol for the views to be no7fied by the model
  15. 15. Pull protocol However, HTTP is a pull protocol: no request implies no response
  16. 16. How can we overcome such limita2ons?
  17. 17. Stateless protocol HTTP is stateless: we can implement the MVC design pa3ern on top of the Java Servlet Pla;orm
  18. 18. Stateless protocol The Java Servlet Pla-orm provides a session context to help track users in the applica8on
  19. 19. Pull protocol HTTP is a pull protocol: we can increase the Controller responsibility
  20. 20. Pull protocol Namely, the Controller will be responsible for: • State changes • State queries • Change no2fica2ons
  21. 21. MVC 2 pa(ern The resul)ng pa.ern is some)mes called MVC 2 or Web MVC +-------------+ +---------------+ +----------------+ | +----------> +---------> | | View | | Controller | | Domain model | | <----------+ <---------+ | +-------------+ +---------------+ +----------------+
  22. 22. MVC 2 pa(ern Any state query or change no0fica0on must pass through the Controller +-------------+ +---------------+ +----------------+ | +----------> +---------> | | View | | Controller | | Domain model | | <----------+ <---------+ | +-------------+ +---------------+ +----------------+
  23. 23. MVC 2 pa(ern The View renders data passed by the Controller rather than data returned directly from the Model +-------------+ +---------------+ +----------------+ | +----------> +---------> | | View | | Controller | | Domain model | | <----------+ <---------+ | +-------------+ +---------------+ +----------------+
  24. 24. MVC 2 pa(ern We refer to such data as the view model +-------------+ +---------------+ +----------------+ | +--------------> +---------> | | View | | Controller | | Domain model | | <--View model--+ <---------+ | +-------------+ +---------------+ +----------------+
  25. 25. Compe&ng architectures Note that MVC 2 proposes a compe&ng architecture to the one we presented during the last lecture ┌──────┐┌────────────────────────────────┐ │ D ││ │ │ o ││ Presentation layer │ │ m ││ │ │ a │└────────────────────────────────┘ │ i │┌────────────────────────────────┐ │ n ││ │ │ ││ Service layer │ │ m ││ │ │ o │└────────────────────────────────┘ │ d │┌────────────────────────────────┐ │ e ││ │ │ l ││ Persistence layer │ │ ││ │ └──────┘└────────────────────────────────┘
  26. 26. Compe&ng architectures We reconcile the two architectures by limi3ng the scope of the MVC 2 pa;ern to the sole presenta(on layer ┌──────┐┌────────────────────────────────┐ │ D ││ │ │ o ││ Presentation layer │ │ m ││ │ │ a │└────────────────────────────────┘ │ i │┌────────────────────────────────┐ │ n ││ │ │ ││ Service layer │ │ m ││ │ │ o │└────────────────────────────────┘ │ d │┌────────────────────────────────┐ │ e ││ │ │ l ││ Persistence layer │ │ ││ │ └──────┘└────────────────────────────────┘
  27. 27. Compe&ng architectures The controller will defer actual computa3on to the service layer +-------------+ +---------------+ +----------------+ | +--------------> +---------> | | View | | Controller | | Service layer | | <--View model--+ <---------+ | +-------------+ +---------------+ +----------------+
  28. 28. What is Spring MVC? Spring MVC is an open source MVC 2 framework for developing Web applica3ons
  29. 29. Spring MVC Spring MVC eases Web applica2on development • It provides a ready-to-use MVC 2 Controller • It promotes Spring’s loosely coupled techniques in the presenta>on layer of an applica>on
  30. 30. Request processing pipeline
  31. 31. DispatcherServlet Spring MVC is designed around a central servlet named DispatcherServlet Presentation layer +---------------------------------+ | | | | | | | +-----------------------+ | | | | | | | DispatcherServlet | | | | | | | +-----------------------+ | | | | | | | | | +---------------------------------+
  32. 32. DispatcherServlet DispatcherServlet acts as a centralized entry point to the Web applica.on Presentation layer +---------------------------------+ | | | | | | +---------------+ | +-----------------------+ | | | Request | | | | | Browser +--------------> DispatcherServlet | | | | | | | | +---------------+ | +-----------------------+ | | | | | | | | | +---------------------------------+
  33. 33. DispatcherServlet That is, every request is handled by DispatcherServlet Presentation layer +---------------------------------+ | | | | | | +---------------+ | +-----------------------+ | | | Request | | | | | Browser +--------------> DispatcherServlet | | | | | | | | +---------------+ | +-----------------------+ | | | | | | | | | +---------------------------------+
  34. 34. DispatcherServlet DispatcherServlet is an expression of the front controller pa.ern Presentation layer +---------------------------------+ | | | | | | +---------------+ | +-----------------------+ | | | Request | | | | | Browser +--------------> Front Controller | | | | | | | | +---------------+ | +-----------------------+ | | | | | | | | | +---------------------------------+
  35. 35. The Front Controller The Front controller’s job is to determine a suitable handler capable of performing the actual processing Presentation layer +---------------------------------+ | | | | | | +---------------+ | +-----------------------+ | | | Request | | | | | Browser +--------------> Front Controller | | | | | | | | +---------------+ | +-----------+-----------+ | | | | | | | | | | | +--------v---------+ | | | | | | | Handler | | | | | | | +------------------+ | | | | | +---------------------------------+
  36. 36. Controllers Handlers are nearly always Spring MVC controllers Presentation layer +---------------------------------+ | | | | | | +---------------+ | +-----------------------+ | | | Request | | | | | Browser +--------------> Front Controller | | | | | | | | +---------------+ | +-----------+-----------+ | | | | | | | | | | | +--------v---------+ | | | | | | | Controller | | | | | | | +------------------+ | | | | | +---------------------------------+
  37. 37. Model The selected Controller interacts with the service layer; the relevant data are collected in a view model Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-------------------+-------+ | | | | | | | | | | | | +--------v----------+ | | | | | Persistence layer | | | | | +--------+----------+ | | | | | | +---v----------+ | | v | | | | | +--+---+ | | Controller <-----+ | | | | | | | DB | | +--------------+ | | | +--------------------------------------+ +------+
  38. 38. Model The selected Controller interacts with the service layer; the relevant data are collected in a view model Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-------------------+-----^-+ | | | | | | | | | | | +---+---+ | | +--------v----------+ | | | Model | | | | Persistence layer | | | +---+---+ | | +--------+----------+ | | | | | | | +---v-----+----+ | | v | | | | | +--+---+ | | Controller <-----+ | | | | | | | DB | | +--------------+ | | | +--------------------------------------+ +------+
  39. 39. Model Spring MVC refers to the view model simply as the model. This may lead to confusion with the classic MVC terminology Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-------------------+-----^-+ | | | | | | | | | | | +---+---+ | | +--------v----------+ | | | Model | | | | Persistence layer | | | +---+---+ | | +--------+----------+ | | | | | | | +---v-----+----+ | | v | | | | | +--+---+ | | Controller <-----+ | | | | | | | DB | | +--------------+ | | | +--------------------------------------+ +------+
  40. 40. Model Regardless the name, remember that the model consists of data the Controller prepares just for the view Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-------------------+-----^-+ | | | | | | | | | | | +---+---+ | | +--------v----------+ | | | Model | | | | Persistence layer | | | +---+---+ | | +--------+----------+ | | | | | | | +---v-----+----+ | | v | | | | | +--+---+ | | Controller <-----+ | | | | | | | DB | | +--------------+ | | | +--------------------------------------+ +------+
  41. 41. Controllers When the controller has finished processing, the front controller determines which view to render Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-------------------+-----^-+ | | | | | | | | | | | +---+---+ | | +--------v----------+ | | | Model | | | | Persistence layer | | | +---+---+ | | +--------+----------+ | | | | | | | +-------------+ +---v-----+----+ | | v | | | | | | | +--+---+ | | View | | Controller <-----+ | | | | | | | | | DB | | +-------------+ +--------------+ | | | +--------------------------------------+ +------+
  42. 42. Views When the controller has finished processing, the front controller determines which view to render Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-------+-----------+-----^-+ | | | | | | | | | | | +---+---+ | +---+---+ | | +--------v----------+ | | Model | | | Model | | | | Persistence layer | | +---+---+ | +---+---+ | | +--------+----------+ | | | | | | | | +--------v----+ +---v-----+----+ | | v | | | | | | | +--+---+ | | View | | Controller <-----+ | | | | | | | | | DB | | +-------------+ +--------------+ | | | +--------------------------------------+ +------+
  43. 43. Views When the controller has finished processing, the front controller determines which view to render Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | | | | | | | +--------+----------+ +-------------+ | +-^-----+-----------+-----^-+ | | | | | | | | | | | | | +---+---+ | +---+---+ | | +--------v----------+ | | | Model | | | Model | | | | Persistence layer | | | +---+---+ | +---+---+ | | +--------+----------+ | | | | | | | | | +--+-----v----+ +---v-----+----+ | | v | | | | | | | +--+---+ | | View | | Controller <-----+ | | | | | | | | | DB | | +-------------+ +--------------+ | | | +--------------------------------------+ +------+
  44. 44. Views When the controller has finished processing, the front controller determines which view to render Presentation layer +--------------------------------------+ | | +-------------+ Request | +---------------------------+ | | +--------------> | | +-------------------+ | Browser | | | Front controller | | +-> Service layer | | +<-------------+ | | | +--------+----------+ +-------------+ Response| +-^-----+-----------+-----^-+ | | | | | | | | | | | | | +---+---+ | +---+---+ | | +--------v----------+ | | | Model | | | Model | | | | Persistence layer | | | +---+---+ | +---+---+ | | +--------+----------+ | | | | | | | | | +--+-----v----+ +---v-----+----+ | | v | | | | | | | +--+---+ | | View | | Controller <-----+ | | | | | | | | | DB | | +-------------+ +--------------+ | | | +--------------------------------------+ +------+
  45. 45. Se#ng up Spring MVC
  46. 46. Se#ng up Spring MVC Se#ng up Spring MVC is a two-step process 1. Loading DispatcherServlet in the Web container 2. Instan5a5ng a DI container and the related beans
  47. 47. 1. Loading DispatcherServlet in the Web container
  48. 48. Loading the front controller We need to tell the Web container to load DispatcherServlet
  49. 49. Loading the front controller To this end, we provide the Web container with a web.xml deployment descriptor file + Web components | (e.g., servlets) | +-------v--------+ | | | Web | web.xml +--------> container | | | +-------+--------+ | | v Web app
  50. 50. Loading the front controller Recall that the web.xml file describes how to deploy the Web components of an applica6on + Web components | (e.g., servlets) | +-------v--------+ | | | Web | web.xml +--------> container | | | +-------+--------+ | | v Web app
  51. 51. Loading the front controller <!-- Load DispatcherServlet --> <servlet> <servlet-name>frontcontroller</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- URL mapping --> <servlet-mapping> <servlet-name>frontcontroller</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
  52. 52. 2. Instan)a)ng a DI container and the related beans
  53. 53. Instan&a&ng beans DispatcherServlet instan'ates a Spring DI container +---------------------------------------------------+ | | | | | | | +------------+ +------------+ | | | +------------+ | +------------+ | | | | +-------------+ | | +-------------+ | | | | | | | | | | | | +-+ | Controllers | +-+ | Special | | | +-+ | +-+ beans | | | +-------------+ +-------------+ | | | | | | | +---------------------------------------------------+ Spring DI Container
  54. 54. Instan&a&ng beans Such a container hosts beans belonging to the presenta(on layer • Controllers • Special beans
  55. 55. Controllers Controllers are wri'en by the developer and provide access to the service layer of the applica5on @Controller public class AccountController { ... }
  56. 56. Special beans Special beans are beans that are already part of Spring MVC
  57. 57. Special beans More precisely, special beans are DispatcherServlet's collaborators
  58. 58. Special beans DispatcherServlet relies on them to process requests and render the appropriate views
  59. 59. Special beans Each special bean plays its own small part in the overall processing of the request
  60. 60. Special beans For instance: • HandlerMapping maps HTTP requests to handlers • ViewResolver maps logical name to views • HandlerExceptionResolver maps excep:ons to handlers
  61. 61. Special bean interfaces Each special bean is expressed as an interface public interface ViewResolver { View resolveViewName(String viewName, Locale locale); }
  62. 62. Special bean advantages Thanks to this, the request processing pipeline is highly flexible and configurable
  63. 63. Special bean advantages Indeed, we can tailor each stage of the pipeline just by changing its concrete implementa9on public class VelocityViewResolver implements ViewResolver { ... } public class XmlViewResolver implements ViewResolver { ... } public class InternalResourceViewResolver implements ViewResolver { ... }
  64. 64. Default special beans For each special bean, the DispatcherServlet maintains a list of implementa)ons to be used by default
  65. 65. Default special beans For instance, InternalResourceViewResolver is instan-ated by default public class InternalResourceViewResolver implements ViewResolver { ... }
  66. 66. Default special beans If not stated otherwise, DispatcherServlet will use default implementa4ons throughout the en4re processing pipeline
  67. 67. Web beans Controllers and special beans are the Web beans of our applica3on +---------------------------------------------------+ | | | | | | | +------------+ +------------+ | | | +------------+ | +------------+ | | | | +-------------+ | | +-------------+ | | | | | | | | | | | | +-+ | Controllers | +-+ | Special | | | +-+ | +-+ beans | | | +-------------+ +-------------+ | | | | | | | +---------------------------------------------------+ Spring DI Container
  68. 68. WebApplicationContext The container we obtain is of type WebApplicationContext +---------------------------------------------------+ | | | | | | | +------------+ +------------+ | | | +------------+ | +------------+ | | | | +-------------+ | | +-------------+ | | | | | | | | | | | | +-+ | Controllers | +-+ | Special | | | +-+ | +-+ beans | | | +-------------+ +-------------+ | | | | | | | +---------------------------------------------------+ Spring DI Container
  69. 69. WebApplicationContext WebApplicationContext extends the ApplicationContext interface with some extra features necessary for Web applica7ons public interface WebApplicationContext extends ApplicationContext { ... }
  70. 70. Configura)on metadata As with any DI container, WebApplicationContext has to be provided with some configura)on metadata + Objects | | | | +---------v---------+ | | | Spring | +-------------> Container | | | Configuration +---------+---------+ metadata | (e.g., XML file) | | v Fully configured system
  71. 71. frontcontroller-servlet.xml In par'cular, the container looks in WEB-INF/ for an XML file named frontcontroller-servlet.xml1 1 More generally, the servletName in servletName-servlet.xml must be the same as the <servlet-name> specified in web.xml
  72. 72. frontcontroller-servlet.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=”..."> <!-- CONFIGURE CONTROLLERS AND SPECIAL BEANS HERE --> </beans>
  73. 73. Overriding defaults By altering frontcontroller-servlet.xml, we can customize or replace default beans within the container
  74. 74. Overriding defaults Example: customizing InternalResourceViewResolver <bean class="org.springframework.web. servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
  75. 75. Wri$ng controllers
  76. 76. Controllers Controllers are responsible for responding to the ac#ons the user takes on the user interface • Submi'ng a form • Clicking on a link • Accessing a page
  77. 77. Types of controllers There exist two op-ons for wri-ng controllers • Using the @Controller annota-on • Implemen-ng the Controller interface2 2 Do not use this approach. The only reason why the Controller interface is s5ll available is to preserve compa5bility with legacy code
  78. 78. Annotated controllers To write annotated controllers we need to use the @Controller annota/on @Controller public class GreetingController { ... }
  79. 79. Annotated controllers The @Controller annota)on indicates that a par)cular class serves the role of a controller @Controller public class GreetingController { ... }
  80. 80. Auto-detec)ng controllers A simple addi+on to frontcontroller-servlet.xml allows the container to auto-detect annotated controllers <context:component-scan base-package="it.polimi.awt.springmvc.web"/>
  81. 81. Auto-detec)ng controllers The <context:component-scan> element recursively scans a package, looking for classes to be automa8cally registered as beans <context:component-scan base-package="it.polimi.awt.springmvc.web"/>
  82. 82. @RequestMapping The @RequestMapping annota)on is used to map URLs to handler methods @Controller public class GreetingController { @RequestMapping("/greeting") public String getGreeting() { ... } }
  83. 83. @RequestMapping The /greeting URL is mapped to getGreeting() @RequestMapping("/greeting") public String getGreeting() { ... }
  84. 84. Unique endpoints Think of handler methods as unique endpoints, with mappings derived from the related @RequestMapping annota6ons @RequestMapping("/greeting") public String getGreeting() {...}
  85. 85. Annotated controllers upsides When you open a controller, you can see which URLs the controller is mapped to @RequestMapping("/greeting") public String getGreeting() {...}
  86. 86. Annotated controllers downsides The mapping is sca$ered throughout the codebase, making it harder to see which URL is mapped to which handler method @RequestMapping("/greeting") public String getGreeting() {...}
  87. 87. Mapping URLs to handlers In order to interpret the mappings defined in the controller class, Spring MVC needs a HandlerMapping implementa8on @RequestMapping("/greeting") public String getGreeting() {...}
  88. 88. Determining which handler to call The HandlerMapping interface provides the abstrac2on for mapping requests to handlers3 public interface HandlerMapping { public HandlerExecutionChain getHandler(HttpServletRequest request); } 3 The getHandler method returns a HandlerExecutionChain only because of the need of accoun4ng for possible interceptors. Conceptually, we can s4ll assume the method to return a handler
  89. 89. Determining which handler to call Each HandlerMapping implementa-on is able to inspect the request and come up with an appropriate handler +----------------+ | | | HandlerMapping | | | +---^------+-----+ | | HTTP | | Handler request | | | | +--+------v----+ +----------------+ | | | | | Dispatcher +-------------> Handler | +-------------> Servlet | | (Controller) | | <-------------+ | HTTP +--------------+ +----------------+ request
  90. 90. Determining which handler to call DispatcherServlet consults one or more HandlerMapping implementa.ons to know which handler to call +----------------+ | | | HandlerMapping | | | +---^------+-----+ | | HTTP | | Handler request | | | | +--+------v----+ +----------------+ | | | | | Dispatcher +-------------> Handler | +-------------> Servlet | | (Controller) | | <-------------+ | HTTP +--------------+ +----------------+ request
  91. 91. Determining which handler to call If no handler is found, a 404 HTTP response is sent back to the client +----------------+ | | | HandlerMapping | | | +---^------+-----+ | | HTTP | | Handler request | | | | +--+------v----+ +----------------+ | | | | | Dispatcher +-------------> Handler | +-------------> Servlet | | (Controller) | | <-------------+ | HTTP +--------------+ +----------------+ request
  92. 92. Overriding HandlerMapping DefaultAnnotationHandlerMapping is the default implementa-on of HandlerMapping public class DefaultAnnotationHandlerMapping implements HandlerMapping { ... }
  93. 93. Overriding HandlerMapping As of Spring 3, the suggested implementa.on became RequestMappingHandlerMapping public class DefaultAnnotationHandlerMapping implements HandlerMapping { ... } public class RequestMappingHandlerMapping implements HandlerMapping { ... }
  94. 94. Overriding HandlerMapping RequestMappingHandlerMapping is a HandlerMapping implementa+on that allows performing more advanced opera+ons • Data valida*on • Wri*ng and reading JSON • Date and numbers support
  95. 95. Overriding HandlerMapping To start using RequestMappingHandlerMapping, it is sufficient to alter frontcontroller-servlet.xml so as to add <mvc:annotation-driven/>
  96. 96. Responsibili*es We already know that the Web layer has two responsibili-es 1. Glueing together the service layer and the Web 2. Taking care of the naviga;on logic
  97. 97. Responsibili*es Let us now see how to implement such responsibili2es in prac(ce 1. Glueing together the service layer and the Web 2. Taking care of the naviga;on logic
  98. 98. 1. Interac+ng with the service layer
  99. 99. Interac(ng with the service layer A"er being invoked, the controller processes the HTTP request and interacts with the service layer +---------------+ +----------------+ | +---------> | | Controller | | Service layer | | <---------+ | +---------------+ +----------------+
  100. 100. GreetingService For instance, we may assume that in our fic3onal applica3on, the user can request a random gree3ng public interface GreetingService { public String getRandomGreeting(); }
  101. 101. GreetingService implementa*on public class NaiveGreetingService implements GreetingService { private List<String> greetings; public NaiveGreetingService() { this.greetings = Arrays.asList( "Hello sweetie", "Valar morghulis", "Tiger tiger" ); } @Override public String getRandomGreeting() { int index = ThreadLocalRandom.current().nextInt(greetings.size()); return greetings.get(index); } }
  102. 102. Execu&ng the use case Within the handler method, we first execute the related use case @Controller public class GreetingController { private GreetingService service; @RequestMapping("/greeting") public String getGreeting() { // execute the related use case String greeting = service.getRandomGreeting(); ... } }
  103. 103. Execu&ng the use case Such an invoca+on may result in an arbitrarily complex object @Controller public class GreetingController { private GreetingService service; @RequestMapping("/greeting") public String getGreeting() { // execute the related use case String greeting = service.getRandomGreeting(); ... } }
  104. 104. Execu&ng the use case However, in this case we end up with a simple String @Controller public class GreetingController { private GreetingService service; @RequestMapping("/greeting") public String getGreeting() { // execute the related use case String greeting = service.getRandomGreeting(); ... } }
  105. 105. Model Once we collected the use case outcome, the next step is to build a model object +--------------+ +--------------------+ +----------------+ | | +----------+ | | +----------+ | | | View <--+ Model +--+ Front Controller <--+ Model +--+ Controller | | | +----------+ | | +----------+ | | +--------------+ +--------------------+ +----------------+
  106. 106. Model This model object will contain the frac%on of the outcome that holds some significance for the next view to render +--------------+ +--------------------+ +----------------+ | | +----------+ | | +----------+ | | | View <--+ Model +--+ Front Controller <--+ Model +--+ Controller | | | +----------+ | | +----------+ | | +--------------+ +--------------------+ +----------------+
  107. 107. Model The view will use the model to build up the dynamic parts of the user interface +--------------+ +--------------------+ +----------------+ | | +----------+ | | +----------+ | | | View <--+ Model +--+ Front Controller <--+ Model +--+ Controller | | | +----------+ | | +----------+ | | +--------------+ +--------------------+ +----------------+
  108. 108. Model The model is the collec+on of named objects needed by the view in order to render itself +---------------+--------------+ | key1 | value1 | +------------------------------+ | key2 | value2 | +------------------------------+ | key3 | value3 | +---------------+--------------+
  109. 109. Model a(ributes These named objects are usually called model a.ributes +---------------+--------------+ | key1 | value1 | +------------------------------+ | key2 | value2 | +------------------------------+ | key3 | value3 | +---------------+--------------+
  110. 110. Model implementa-ons Several data structures can be used for represen2ng a model • Any implementa-on of java.util.Map • Any implementa-on of the Model interface provided by Spring • A ModelMap object provided by Spring
  111. 111. Model as an input argument Regardless the specific implementa2on, it is common prac2ce to let the framework provide the model directly as an input argument public String getGreeting(Map<String, Object> model) {...} public String getGreeting(Model model) {...} public String getGreeting(ModelMap model) {...}
  112. 112. Model as a Map The only requirement when using java.util.Map to store model a4ributes is that the key has to be of type String @RequestMapping("/greeting") public String getGreeting(Map<String, Object> model) { String greeting = service.getRandomGreeting(); model.put("greeting", greeting); ... }
  113. 113. Model as a Map The value part of the map can be freely decided. Because of its generality, Object is a popular choice @RequestMapping("/greeting") public String getGreeting(Map<String, Object> model) { String greeting = service.getRandomGreeting(); model.put("greeting", greeting); ... }
  114. 114. Model as a Model The downside of using a Map is that we have to decide the name of each model a)ribute we want to store // deciding names... boring (and difficult!) model.put("greeting", greeting);
  115. 115. Model as a Model The Model interface provides convenient methods for popula4ng the Model, such as addAttribute() @RequestMapping("/special-deals") public String getSpecialDeals(Model model) { List<SpecialDeal> specialDeals = service.getSpecialDeals(); model.addAttribute(specialDeals); ... }
  116. 116. Model as a Model addAttribute() is the same as Map’s put(), except that it automa&cally generates the name for the model a5ribute @RequestMapping("/special-deals") public String getSpecialDeals(Model model) { List<SpecialDeal> specialDeals = service.getSpecialDeals(); model.addAttribute(specialDeals); ... }
  117. 117. Naming strategy • Scalar objects take the uncapitalized, unqualified class name • Collec.on objects take the uncapitalized, unqualified class name of the first object in the collec:on, with List appended to the name
  118. 118. Naming strategy Examples: • com.myapp.Product becomes product • List<com.myapp.Product> becomes productList
  119. 119. You can s)ll decide the names If needed, it is s+ll possible to decide the name of each model a4ribute @RequestMapping("/fullname") public String getFullname(Model model) { // as both "Jon" and "Snow" are of type // String, it is better to explicitly name them model.addAttribute("name", "Jon"); model.addAttribute("surname", "Snow"); ... }
  120. 120. Model as ModelMap The ModelMap class is a Map, but it provides some addi4onal conveniences w.r.t. the plain Map interface @RequestMapping("/fullname") public String getFullname(Model model) { // chained calls are handy! model.addAttribute("name", "Jon") .addAttribute("surname", "Snow"); ... }
  121. 121. Model as ModelMap Namely: • It adheres to the same naming conven2on as Model • The addAttribute() method checks if the values are null • It supports chained calls of the addAttribute() method
  122. 122. 2. Taking care of the naviga2on logic
  123. 123. Choosing the next view When processing is complete, the controller is responsible for choosing what view the user sees next +--------------+ +--------------------+ +----------------+ | | +----------+ | | +----------+ | | | View <--+ Model +--+ Front Controller <--+ Model +--+ Controller | | | +----------+ | | +----------+ | | +--------------+ +--------------------+ +----------------+
  124. 124. The View renders the model Views are responsible for rendering the objects in the Model +--------------+ +--------------------+ +----------------+ | | +----------+ | | +----------+ | | | View <--+ Model +--+ Front Controller <--+ Model +--+ Controller | | | +----------+ | | +----------+ | | +--------------+ +--------------------+ +----------------+
  125. 125. The View interface Spring MVC does not make any assump)on on the specific view technology • JavaServer Pages • JavaServer Faces • Velocity
  126. 126. The View interface To this end, views are modeled according to the View interface public interface View { void render(Map<String,?> model, HttpServletRequest request, HttpServletResponse response) String getContentType(); }
  127. 127. The View interface As with many Spring’s interfaces, the View interface is really simple public interface View { void render(Map<String,?> model, HttpServletRequest request, HttpServletResponse response) String getContentType(); }
  128. 128. The render() method The View will render the output star2ng from • The Model • The Servlet’s request and response objects
  129. 129. The render() method The render() method returns void to denote that it is the arriving point of the en0re request processing pipeline7 void render(Map<String,?> model, HttpServletRequest request, HttpServletResponse response) 7 Here, we are not considering possible calls to HandlerInterceptor.afterCompletion()
  130. 130. The render() method Hence, it is the responsibility of the View not only to render the content, but also to actually return it to the client void render(Map<String,?> model, HttpServletRequest request, HttpServletResponse response)
  131. 131. Wri$ng a View implementa$on Given the interface, we can easily write a View implementa4on public class GreetingView implements View { @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { PrintWriter out = response.getWriter(); out.print(model.get("greeting")); out.flush(); out.close(); } @Override String getContentType() { ... } }
  132. 132. View implementa*ons However, most probably we would prefer to use a specific view technology, rather than implemen9ng our own Views
  133. 133. View technology independence Spring MVC makes a special effort to keep the controller unaware of the adopted view technology @RequestMapping("/greeting") public String getGreeting(Model model) { ... return "greeting"; }
  134. 134. View technology independence Such a decoupling is achieved by referring to views by their logical name @RequestMapping("/greeting") public String getGreeting(Model model) { ... return "greeting"; }
  135. 135. View technology independence In order to enforce decoupling, we let the controller knows nothing of the view but its logical name @RequestMapping("/greeting") public String getGreeting(Model model) { ... return "greeting"; }
  136. 136. ViewResolver The special bean ViewResolver will later resolve the view’s logical name to an actual view instance public interface ViewResolver { View resolveViewName(String viewName, Locale locale); }
  137. 137. ViewResolver Implementa)ons of ViewResolver are able to provide the mapping between logical names and View objects +-----------------+ | | | ViewResolver | | | +---+-----------^-+ | | +---v----+ | | View | | +---+----+ | | | +-----v-----------+---+ +----------------+ | | | | | DispatcherServlet <-------+ Controller | | | | | +---------------------+ +----------------+
  138. 138. getGreeting() @RequestMapping("/greeting") public String getGreeting(Model model) { String greeting = service.getRandomGreeting(); model.addAttribute("greeting", greeting); return "greeting"; }
  139. 139. Controller testability Note that this allows controllers to be easily unit-tested6 public class GreetingControllerTest { @Test public void getGreetingTest() { GreetingController controller = new GreetingController(...); Map<String, Object> model = new HashMap<>(); String viewName = controller.getGreeting(model); assertTrue(viewName.equals("greeting")); assertTrue(model.get("expression") != null); } } 6 Snippet adapted from h0p://stackoverflow.com/a/9363053/1849221
  140. 140. InternalResourceViewResolver The most commonly used ViewResolver when developing with JSP is the InternalResourceViewResolver
  141. 141. InternalResourceViewResolver InternalResourceViewResolver obtains the psychical view loca1on by surrounding the logical name with a prefix and a suffix
  142. 142. InternalResourceViewResolver We need to configure InternalResourceViewResolver in frontcontroller-servlet.xml <bean class="org.springframework.web. servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
  143. 143. Hiding JSP pages It is good prac-ce to place all view pages under the /WEB-INF directory
  144. 144. Hiding JSP pages This protects the pages from being retrieved independently of the Controllers that configure them
  145. 145. References
  146. 146. References • Stackoverflow, Design pa5erns for Web applica:ons • SpringSource, Spring Framework Reference • SpringSource, Java-doc APIs • Stackoverflow, ModelMap usage in Spring
  147. 147. References • S. Ladd, K. Donald, Expert Spring MVC and Web flows, Apress PublicaBons • M. Deinum, K. Serneels, Pro Spring MVC: with Web flows, Apress PublicaBons • Craig Walls, Spring in AcBon (3rd EdiBon), Manning PublicaBons • T. N. Husted et al., Struts 1 In AcBon, Manning PublicaBons
  148. 148. References • Clarence Ho, Rob Harrop, Pro Spring 3, Apress Publica8ons • Rod Johnson et al., Professional Java Development with the Spring Framework, Wiley Publishing

×