Spring 5 Web MVC Example

Spring DispatcherServlet – How does it work?

Learn about Spring’s DispatcherServlet, its responsibilities and how to configure it in web applications using XML and Java configurations. The DispatcherServlet is responsible for handling incoming HTTP requests and delegating them to the appropriate controller method for processing.

1. What is DispatcherServlet?

The DispatcherServlet acts as the front controller for Spring-based web applications. It provides a mechanism for request processing where actual work is performed by configurable and delegated components (usually controllers). It is inherited from HttpServlet and is typically configured in the web.xml file.

Spring dispatcher servlet

A web application can define any number of DispatcherServlet instances. Each instance will operate in its own namespace, loading its own application context with mappings, handlers, etc. Only the root application context is loaded by ContextLoaderListener, if any, will be shared. In most cases, applications have only a single DispatcherServlet with the context-root URL (/) , that is, all requests coming to that domain will be handled by it.

The DispatcherServlet uses Spring configuration classes to discover the delegate components it needs for request mapping, view resolution, exception handling etc.

2. How DispatcherServlet uses WebApplicationContext?

Let’s understand how the dispatcher servlet works internally? In a Spring-based application, our application objects live within a Java bean container. This container creates objects and associations between objects and manages their complete life cycle. These objects are called Spring-managed beans (or simply beans), and the container is called an application context (via class ApplicationContext).

TheWebApplicationContext is an extension of a plain ApplicationContext and is web-aware. It has ServletContext information. When DispatcherServlet is loaded, it looks for the bean configuration file (XML configuration) or @Configuration classes (Java configuration) and initializes it.

By having access to the Servlet context, any spring bean which implements ServletConextAware interface – can get access to ServletContext instance and do many things with it. For example, it can get context init parameters, get context root information and get resources location inside web application folders.

3. DispatcherServlet XML Configuration

Let’s see how a typical DispatcherServlet declaration and initialization looks. The following code initializes the DispatcherServlet for URL pattern “/*” and loads the bean definitions from the file ‘/WEB-INF/dispatcher-servlet-context.xml‘.

  org.springframework.web.context.ContextLoaderListener  contextConfigLocation /WEB-INF/dispatcher-servlet-context.xml  dispatcher-servlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation  1  dispatcher-servlet /*  

The following dispatcher-servlet-context.xml file demonstrates bean definitions and associations that will be available to DispatcherServlet.

These bean definitions may override any bean definition defined with the same name in the global scope.

4. DispatcherServlet Java Configuration

Starting from Servlet 3.0, in addition to the declarative configuration in the web.xml file, DispatcherServlet can be configured programmatically by implementing or extending either of these three support classes provided by Spring –

4.1. Using WebApplicationInitializer

In the below class, WebApplicationInitializer interface ensures that class ApplicationInitializer is detected by SpringServletContainerInitializer (which itself is bootstrapped automatically) and used to initialize any Servlet 3 container.

In the following example, ApplicationInitializer loads the bean definitions from an XML file.

public class ApplicationInitializer implements WebApplicationInitializer < @Override public void onStartup(ServletContext servletContext) throws ServletException < XmlWebApplicationContext appContext = new XmlWebApplicationContext(); appContext.setConfigLocation("/WEB-INF/dispatcher-servlet-context.xml"); ServletRegistration.Dynamic registration = servletContext.addServlet("rootDispatcher", new DispatcherServlet(appContext)); registration.setLoadOnStartup(1); registration.addMapping("/"); >>

In the following example, ApplicationInitializer loads the bean definitions from annotated Java configuration class.

public class ApplicationInitializer implements WebApplicationInitializer < @Override public void onStartup(ServletContext container) < AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(AppConfig.class); container.addListener(new ContextLoaderListener(rootContext)); AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); dispatcherContext.register(DispatcherConfig.class); ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); >>

In the above code, AppConfig and DispatcherConfig classes define the spring-managed beans which will be in the web application context.

4.2. Using AbstractDispatcherServletInitializer

This is the base class for WebApplicationInitializer implementations that register a DispatcherServlet in the servlet context.

public class ApplicationInitializer extends AbstractDispatcherServletInitializer < @Override protected WebApplicationContext createRootApplicationContext() < return null; >@Override protected WebApplicationContext createServletApplicationContext() < XmlWebApplicationContext cxt = new XmlWebApplicationContext(); cxt.setConfigLocation("/WEB-INF/dispatcher-servlet-context.xml"); return cxt; >@Override protected String[] getServletMappings() < return new String[] < "/" >; > //Register filters @Override protected Filter[] getServletFilters() < return new Filter[] < new HiddenHttpMethodFilter(), new CharacterEncodingFilter() >; > >

Please note that if we need to customize the DispatcherServlet, we can override the createDispatcherServlet() method.

4.3. Using AbstractAnnotationConfigDispatcherServletInitializer

This class extends AbstractDispatcherServletInitializer and does a few things implicitly which otherwise you could be doing yourself. An added advantage is that you can now use the convenience classes provided by Spring instead of manually configuring the DispatcherServlet and/or ContextLoaderListener.

It is the preferred approach for applications that use Java-based Spring configuration. It enables you to start the servlet application context as well as the root application context.

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer < @Override protected Class[] getRootConfigClasses() < return new Class[] < RootConfig.class >; > @Override protected Class[] getServletConfigClasses() < return new Class[] < WebMvcConfig.class >; > @Override protected String[] getServletMappings() < return new String[] < "/" >; > >

Here RootConfig and WebMvcConfig classes are used to configure beans in root and servlet context scope.

5. Beans Supported by DispatcherServlet

Upon receiving a web request, DispatcherServlet performs a set of operations for request processing. It used a set of supporting beans for this. This table lists these default configured beans and their responsibilities –

Bean Responsibilities
HandlerMapping Maps incoming web requests to handlers and pre- and post-processors
HandlerAdapter Invokes the handler which resolves arguments and dependencies, such as annotated arguments for URL-mapped controller method endpoints
HandlerExceptionResolver Allows programmatic handling of exceptions and maps exceptions to views
ViewResolver Resolves logical view names to view instances
LocaleResolver Resolves the client’s locale in order to enable internationalization
LocaleContextResolver A richer extension of LocaleResolver , with timezone information
ThemeResolver Resolves themes configured in your app for enhanced user experience
MultipartResolver Handles multipart file uploads as part of HTTP requests
FlashMapManager Manages FlashMap instances that store temporary Flash attributes between requests redirected from one another

If you want to change any particular behavior of any bean, then you need to override it.

6. DispatcherServlet in Spring Boot

In a Spring Boot application, the DispatcherServlet is automatically configured and initialized when the spring-boot-starter-web dependency is found in the classpath. During startup, Spring scans the application classpath for @Controller and other related annotations. To explicitly trigger the scanning, we can use @EnableWebMvc annotation on any @Configuration class

@Configuration @EnableWebMvc @ComponentScan(basePackageClasses = MyConfiguration.class) public class MyConfiguration < //. >

All such annotated classes and interfaces are configured including other supported beans based on certain defaults and conventions provided by WebMvcConfigurationSupport.

To customize any default bean, implement the WebMvcConfigurer interface and override the respective method.

@Configuration @EnableWebMvc @ComponentScan(basePackageClasses = MyConfiguration.class) public class MyConfiguration implements WebMvcConfigurer < @Override public void configureMessageConverters(List> converters) < converters.add(new MyHttpMessageConverter()); >>

7. DispatcherServlet Example

To demo the use of DispatcherServlet , I have written a very minimum application that just configures the dispatcher servlet and overrides the view resolver bean.

package com.howtodoinjava.demo.spring.config; public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer < @Override protected Class[] getRootConfigClasses() < return new Class[] < >; > @Override protected Class[] getServletConfigClasses() < return new Class[] < WebMvcConfig.class >; > @Override protected String[] getServletMappings() < return new String[] < "/" >; > >
@Configuration @EnableWebMvc @ComponentScan(basePackages = < "com.howtodoinjava.demo.spring">) public class WebMvcConfig implements WebMvcConfigurer < @Bean public InternalResourceViewResolver resolver() < InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; >>
@Controller public class HomeController < @GetMapping("/") public String homeInit(Locale locale, Model model) < return "home"; >>
    

HowToDoInJava.com

Spring 5 Web MVC DispatcherServlet Example

Источник

DispatcherServlet

Spring MVC, как и многие другие веб-фреймворки, разработан по проектному шаблону «единой точки входа (front controller)», где центральный Servlet , DispatcherServlet , обеспечивает общий алгоритм обработки запросов, а фактическая работа выполняется настраиваемыми компонентами-делегатами. Эта модель является гибкой и поддерживает различные рабочие процессы.

DispatcherServlet , как и любой другой Servlet , необходимо объявлять и отображать в соответствии со спецификацией сервлетов с помощью конфигурации Java или в web.xml . В свою очередь, DispatcherServlet использует конфигурацию Spring для обнаружения компонентов-делегатов, необходимых ему для отображения запросов, распознавание представлений, обработки исключений и т. д.

В следующем примере конфигурации Java регистрируется и инициализируется DispatcherServlet , который автоматически обнаруживается контейнером сервлетов:

public class MyWebApplicationInitializer implements WebApplicationInitializer < @Override public void onStartup(ServletContext servletContext) < // Загружаем конфигурацию веб-приложения Spring AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(AppConfig.class); // Создаем и регистрируем DispatcherServlet DispatcherServlet servlet = new DispatcherServlet(context); ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet); registration.setLoadOnStartup(1); registration.addMapping("/app/*"); >>
class MyWebApplicationInitializer : WebApplicationInitializer < override fun onStartup(servletContext: ServletContext) < // Загружаем конфигурацию веб-приложения Spring val context = AnnotationConfigWebApplicationContext() context.register(AppConfig::class.java) // Создаем и регистрируем DispatcherServlet val servlet = DispatcherServlet(context) val registration = servletContext.addServlet("app", servlet) registration.setLoadOnStartup(1) registration.addMapping("/app/*") >>

Помимо использования ServletContext API напрямую, также можно расширить AbstractAnnotationConfigDispatcherServletInitializer и переопределить заданные методы.

Для программных случаев использования в качестве альтернативы AnnotationConfigWebApplicationContext может использоваться GenericWebApplicationContext .

Следующий пример конфигурации web.xml регистрирует и инициализирует DispatcherServlet :

  org.springframework.web.context.ContextLoaderListener  contextConfigLocation /WEB-INF/app-context.xml  app org.springframework.web.servlet.DispatcherServlet contextConfigLocation  1  app /app/*  

Spring Boot придерживается иной последовательности инициализации. Вместо того чтобы выполнять привязку к жизненному циклу контейнера сервлетов, Spring Boot использует конфигурацию Spring для начальной самозагрузки и начальной загрузки встроенного контейнера сервлетов. Объявления Filter и Servlet обнаруживаются в конфигурации Spring и регистрируются в контейнере сервлетов.

Источник

Читайте также:  Javascript формы html страницы
Оцените статью