Spring Framework — Recap MVC module
Spring Web MVC framework
Spring web MVC framework is request-driven and designed around DispatcherServlet. It means all incoming requests go through a single servlet — DispatcherServlet
(Front controller)
Dispatcher Servlet
It’s a servlet that takes the incoming request and delegates the processing of that request to one of the handlers (Controllers).
DispatcherServlet initialization parameters
There are 3 important parameters which are
contextClass
— default isXmlWebApplicationContext
contextConfigLocation
— used by thecontextClass
to load configuration if the file/WEB-INF/[servlet-name]-servlet.xml
is absentnamespace
— default is[servlet-name]-servlet
Context Hierarchy
We can have multiple application contexts in a parent-child relationship. A child can have one parent only but a Parent can have multiple child contexts.
The root should contain all infrastructure beans that should be shared between your other contexts and Servlet instances. These inherited beans can be overridden in the servlet-specific scope.
Special bean types in the WebApplicationContext
In order to provide the correct view, the Spring framework has some special beans which are given below.
HandlerMapping
— According to some criteria this bean maps oncoming requests to handlers and handler interceptors.HandlerAdapter
— Irrespective of what the handler is really called, it helps the DispatcherServlet to call a handler mapped to a requestHandlerExceptionResolver
— This bean maps exceptions to views and also permits complex exception handling.ViewResolver
— This bean actually resolves view names, provided as strings, into actual view types.LocalResolver
&LocalContextResolver
— This bean resolves the locale of the client.ThemeResolver
— This bean resolves the themes which can be utilized by your application.MultipartResolver
— This bean parses multi-part requests. For example, file uploading using HTML forms.FlashMapManager
— The input and the output FlashMap is stores and retrieves by this bean to pass on attributes from one request to another generally around a redirect.
The default configuration for these beans is available in DispatcherServlet.properties
in the package org.springframework.web.servlet
. Below we have given DispatcherServlet.properties
in two different versions.
DispatcherServlet Processing Sequence
When a request is received by DispatcherServlet
by the Web Container, then
WebApplicationContext
is bound to it as an attribute, key =DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE
- a locale resolver is bound to the request
- a theme resolver is bound to the request
- if a request is found as multipart, then the request is wrapped as
MultipartHttpServletRequest
- a handler is searched for the request and executed (preprocessor, postprocessor, and controller)
- the corresponding view is returned for a model
- Handler exception resolver picks up any exception thrown
Let us start with Controllers and then look at how Spring finds a Controller Bean for a request later.
Controllers
It is the Handler
of the request. It interprets user input and transforms it into a model that is represented to the user by the view.
Annotations used for Handler are
@Controller
@RequestMapping
, — or we can have specific annotations like@GetMapping
/@PostMapping
/@PutMapping
/@DeleteMapping
/@PatchMapping
@RequestParam
@RequestBody
@ModelAttribute
@ResponseBody
URI Template Patterns
Spring provides different features with respect to how we can use request patterns.
- URI-like string, containing one or more variable names e.g.
/owners/{ownerId}
- use the
@PathVariable
annotation on a method argument to bind it to the value of a URI template variable - supports the use of regular expressions in URI template variables
{varName:regex}
- ant style path patterns are supported
/owners/*/pets/{petId}
(seeAntPathMatcher
)
Media Types
If we would like to define the structure of the resource that we are rendering or consuming, we can use media type to define. It also helps in versioning the API.
consumes
- matched only if theContent-Type
request header matchesproduces
- matched only if theAccept
request header matches
Handler Mapping
HandlerMapping
beans in the web application context maps requested URLs to the handler methods/objects.
Types
BeanNameUrlHandlerMapping
— handler sees bean name as URI to matchSimpleUrlHandlerMapping
— allows for direct and declarative mapping between either bean instances and URLs or between bean names and URLs.ControllerClassNameHandlerMapping
— maps URL to a registered controller bean that has, or starts with, the same name but this is removed in Spring 5.DefaultAnnotationHandlerMapping
— deprecatedRequestMappingHandlerMapping
— maps methods annotated with@RequestMapping
(type-level and method-level mappings)
Configuration
Let us see how these Handler Mappings are defined in Spring Configuration.
HandlerExecutionChain
HandlerExecutionChain
contain the handler that matches the incoming request, and may also contain a list of handler interceptors that are applied to the request.
When HandlerMapping returns HandlerExecutionChain, the dispatcher servlet hands the request to the interceptor and Handler defined in HandlerExecutionChain for processing.
At the end of the processor chain, is a handler. The dispatcher servlet encapsulates the handler through the handler adapter and calls the handler processing method according to the unified adapter interface.
HandlerAdapter
HandlerAdapter
is responsible to invoke a handler method and also to return the response as ModelAndView
to the DispatcherServlet
.HandlerMapping
maps a method to a specific URL. DispatcherServlet
then uses a HandlerAdapter
to invoke this method.
Types of HandlerAdapter
There are different types of Handler Adapters available.
HttpRequestHandlerAdapter
— map the requested URL tohandleRequest()
ofHttpRequestHandler
and no view returnedSimpleControllerHandlerAdapter
— deals with classes implementingController
interface and callshandleRequest()
method inController
SimpleServletHandlerAdapter
— forwards the request fromDispatcherServlet
to the appropriateServlet
class and callsservice()
method inServlet
AnnotationMethodHandlerAdapter
— execute the methods that are annotated with@RequestMapping
annotation and performs method-level mapping. Handler mapping class isDefaultAnnotationHandlerMapping
(performs type-level mapping). This is deprecated from Spring 3.2.RequestMappingHandlerAdapter
— handler mapping classRequestMappingHandlerMapping
Configuration for default Handler Mapping and Adapter
We can configure the Default Handler Mapping and Adapter as below.
Message converters for Handler Adapter
RequestMappingHandlerAdapter
convert the request body to the method argument by using differentHttpMessageConverter
.
Different types of HttpMessageConverter
are given below.
ByteArrayHttpMessageConverter
converts byte arrays.StringHttpMessageConverter
converts strings.FormHttpMessageConverter
converts form data to/from a MultiValueMap<String, String>.SourceHttpMessageConverter
converts to/from ajavax.xml.transform.Source
Alternatively, using mvc
namespace
Handler Interceptor
Handler interceptor is used to perform actions before handling, after handling, or after completion (when the view is rendered), of a request. It is used to apply some type of processing to the requests.
There are 3 important methods
prehandle()
– called before the actual handler is executed, but the view is not generated yetpostHandle()
– called after the handler is executedafterCompletion()
– called after the complete request has finished and the view was generated
HandlerInterceptorAdapter
Sometimes we may implement only the required methods instead of all three methods. This is deprecated in Spring 5, we can use HandlerInterceptor
having default methods.
Registering Interceptor
Lets us see two ways to register the handler mappings in Spring MVC.
- Using mvc namespace
2. using HandlerMapping
View Resolvers
Spring enables us to render the model to the browser via ViewResolver
. All handler methods must resolve to a logical view name. It may be explicitly by returning `String`, `View` or `ModelAndView` or implicitly by conventions.
Views are addressed by a logical view name and are resolved by a view resolver.
Types
AbstractCachingViewResolver
XmlViewResolver
ResourceBundleViewResolver
UrlBasedViewResolver
InternalResourceViewResolver
VelocityViewResolver
/FreeMarkerViewResolver
ContentNegotiatingViewResolver
Configuration
- InternalResourceViewResolver
- XmlViewResolver
- ResourceBundleViewResolver
Redirecting to Views
Different ways to redirect to view.
- For
InternalResourceView
, the servlet callsRequestDispatcher.forward(..)
orRequestDispatcher.include()
redirect:
prefix tells theUrlBasedViewResolver
that effectively the controller had returned aRedirectView
- For
RedirectView
, the servlet callsHttpServletResponse.sendRedirect()
forward:
prefix tells theUrlBasedViewResolver
that effectively the controller had returned aInternalResourceView
Flash Attributes
It is a way for one request to store attributes intended for use in another in a Post/Redirect/Get
pattern. They are saved in session
before redirect, and made available in the redirect request and it is removed immediately.
Exception handling
HandlerExceptionResolver
To resolve exceptions thrown during processing an HTTP request.
Types
DefaultHandlerExceptionResolver
resolves standard spring exceptions to their error codes (HTTP 4xx or 5xx)SimpleMappingExceptionResolver
allows taking the class name of any exception that might be thrown and mapping it to a view name.AnnotationMethodHandlerExceptionResolver
— used to handle methods annotated with@ExceptionHandler
. It is deprecated in Spring 3.2ExceptionHandlerExceptionResolver
— exception handler methods defined in Controller/ Controller Advice with@ExceptionHandler
ResponseStatusExceptionResolver
—@ResponseStatus
annotation available on custom exceptions and to map these exceptions to HTTP status codes.- custom exception resolvers can extend
AbstractHandlerExceptionResolver
Configuration
SimpleMappingExceptionResolver
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
Controller Advice
Controller Advice is used to implement common processes which are to be executed in multiple Controllers.
Example
- method with
@InitBinder
- method with
@ExceptionHandler
- method with
@ModelAttribute
This is based on AOP
- as Exception Handling is a cross-cutting concern (hint ‘Advice’ in @ControllerAdvice
) This is handled by ExceptionHandlerExceptionResolver
.