Building web applications with Spring Web MVC
3.1 Spring Web MVC background
To understand Spring Web MVC, it will be useful to understand web-based MVC frame-works in general, Spring’s version of web MVC, and the highlights of Spring Web MVC architecture, including the key components and control flow through those compo-nents. We’ll cover each of those topics now.
3.1.1 A review of the model-view-controller (MVC) pattern
Model-view-controller (MVC) refers to the architectural pattern in which you sepa-rate your business services and domain objects (the model) from the UI (the view) and mediate their interaction through one or more controllers. You’d like to be able to modify your UI without having to change your business logic and domain objects, and separating the model and view makes it easier to do just that. It’s a simple but proven concept.
Java web applications typically realize MVC in roughly the following way: the model encompasses business-tier code (service beans, POJOs, Enterprise JavaBeans [EJBs], and so forth), the view involves JSPs or similar technologies, and the controller is usu-ally servlet-based. HTTP requests come into the servlet, which routes the request to a handler component (sometimes called an action, sometimes called a controller) that in turn processes the request. The handler makes any necessary calls against the service tier and grabs any domain objects1 it needs to populate the view. Finally, the handler figures out which view to deliver and forwards processing to that view. Figure 3.1 shows the typical flow.
The flow works like this. As shown in figure in 3.1, an HTTP request comes into the controller
B
. The controller accesses the modelC
, possibly getting dataD
, possibly updating the model, and possibly both. The controller then uses the viewE
to gener-ate a responseF
, passing any relevant data it pulled out of the model. The client receives the generated responseG
, and service is complete.1 It’s not always desirable to use domain objects in the presentation layer. See section 3.3.1 for a more detailed discussion of this topic.
The separation of concerns is clear. The model is insulated from changes to the view, and the view is insulated from at least certain changes to the model. Of course, because the view renders model data, the view isn’t completely insulated from model changes. But in general, separating the model and view into separate components means it’s easier to update one without breaking the other.
We’ll begin by exploring what Spring Web MVC is and how it helps us build web applications.
3.1.2 What is Spring Web MVC?
Spring Web MVC, as you might guess, is Spring’s web-centric MVC framework. Its primary job is to support the MVC way of dividing application functionality, so it provides explicit support for organizing the web layer into models, views, and controllers. Separation between the three concerns is clean; for example, when a controller selects a view, it does so by selecting only a view name (not a View object, not a hardcoded path), and depen-dency injection makes it possible to treat even view names as injected values.
Besides a clean separation of concerns, another major design goal for Spring Web MVC is flexibility. There are many ways for you to customize the way it works. If you want to use POJO controllers, you can do that. If you prefer defining an interface for con-trollers, you can do that too. You can control how requests map to concon-trollers, how view names are generated, and how view names are resolved to views. You can define inter-ceptor chains and exception handling for your controllers, and you can choose from dif-ferent strategies for resolving locales, UI themes, multipart resolvers, and more.
NOTE Spring 3 deprecates the org.springframework.web.servlet.mvc .Controller hierarchy, so we will not cover these interfaces and classes here.
Spring 3 controllers are generally POJOs.
Figure 3.1 A conceptual view of control flow in web-based model-view-controller applications
Speaking of flexibility, one of our favorite things about Spring Web MVC is the tremen-dous flexibility it provides around handler2 method parameters and return values: if you want to expose an HttpServletRequest to a handler method, just declare the parameter, and it’s automatically provided to the method. If you don’t want it, leave it out. You can do the same thing with a whole host of parameters, as you’ll see.
Don’t worry if that sounds like mumbo-jumbo at this point. We’ll look at this in detail over the course of the chapter. Suffice it to say that Spring Web MVC is flexible and capable.
Let’s see some highlights of the Spring Web MVC architecture.
3.1.3 An architectural overview of Spring Web MVC
The center of the Spring Web MVC universe is the DispatcherServlet, a front con-troller3 that dispatches requests to registered request handlers. The handlers can be UI controllers or endpoints for HTTP-based remote services. Each handler performs a service and then specifies a view to which the DispatcherServlet passes the request.
See figure 3.2.
2 In Spring Web MVC, handler is a more general way of referring to a UI controller. The idea is the same, but handlers include HTTP-based remote service endpoints, which wouldn’t normally be considered UI control-lers even though in reality they’re doing roughly the same thing: grabbing data and exporting it in a desired format. We’ll mostly use handler and controller interchangeably.
3 A front controller is a top-level controller. It often manages other controllers. See Core J2EE Patterns—Front Controller, Oracle, http://mng.bz/AB9X for more information.
Figure 3.2 A conceptual view of con-trol flow in Spring Web MVC
We’re still dealing with the conceptual here, so don’t take figure 3.2 too literally, but here’s how it works. The request comes into the DispatcherServlet
B
. Based on the request path, the DispatcherServlet figures out which of its registered handlers is the right one to service the requestC
. It then passes the HTTP request (or, more abstractly, the user command or form data that the request represents) to a handler for processingD
. The handler queries or updates the model (or both)E
, and if appro-priate the model returns the requested dataF
. The handler then returns both the data and a logical view name back to the DispatcherServletG
. The DispatcherServlet resolves the view name into an actual viewH
and then passes the model data (if any) along to that viewI
so it can be used in generating a responseJ
. Processing is com-plete, and the DispatcherServlet has serviced the request1)
.We’ve suppressed a lot of details, but now you have a basic understanding of how Spring Web MVC works. Let’s get right to the good stuff: writing your first Spring Web MVC application (a toy app) and seeing it in action.