
The Dispatcher servlet
We put values into the model, and we created the view that can read those values from the model. So, the Controller acts as an intermediate between the View and the Model; with this, we have finished all the coding part required to present the welcome page. So will we be able to run our project now? No. At this stage, if we run our project and enter the URL http://localhost:8080/webstore/
on the browser, we will get an HTTP Status 404 error. This is because we have not performed any servlet mapping yet.
Tip
So what is servlet mapping? Servlet mapping is a configuration of mapping a servlet to a URL or URL pattern. For example, if we map a pattern like /status/*
to a servlet, all the HTTP request URLs starting with a text status
such as http://example.com/status/synopsis
or http://example.com/status/complete?date=today
will be mapped to that particular servlet. In other words, all the HTTP requests that carry the URL pattern /status/*
will be handed over to the corresponding mapped servlet class.
In a Spring MVC project, we must configure a servlet mapping to direct all the HTTP requests to a single front servlet. The front servlet mapping is a design pattern where all requests for a particular web application are directed to the same servlet. This pattern is sometimes called as Front Controller Pattern. By adapting the Front Controller design, we make front servlet have total control over the incoming HTTP request so that it can dispatch the HTTP request to the desired controller.
One such front servlet given by Spring MVC framework is the Dispatcher servlet (org.springframework.web.servlet.DispatcherServlet
). We have not configured a Dispatcher servlet for our project yet; this is why we get the HTTP Status 404 error if we run our project now.
Time for action - configuring the Dispatcher servlet
The Dispatcher servlet is what examines the incoming HTTP request and invokes the right corresponding controller method. In our case, the welcome
method from the HomeController
class needs to be invoked if we make an HTTP request by entering the http://localhost:8080/webstore/
URL on the browser. So let's configure the Dispatcher servlet for our project:
- Create a class called
WebApplicationContextConfig
under thecom.packt.webstore.config
package in the source directorysrc/main/java
and add the following code into it:package com.packt.webstore.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation .DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation .EnableWebMvc; import org.springframework.web.servlet.config.annotation .WebMvcConfigurerAdapter; import org.springframework.web.servlet.view .InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @ComponentScan("com.packt.webstore") public class WebApplicationContextConfig extends WebMvcConfigurerAdapter { @Override public void configureDefaultServletHandling (DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Bean public InternalResourceViewResolver getInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/jsp/"); resolver.setSuffix(".jsp"); return resolver; } }
- Create a class called
DispatcherServletInitializer
under thecom.packt.webstore.config
package in the source directorysrc/main/java
and add the following code into it:package com.packt.webstore.config; import org.springframework.web.servlet.support .AbstractAnnotationConfigDispatcherServletInitializer; public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { WebApplicationContextConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
What just happened?
If you know about servlet programming, you might be quite familiar with the servlet configuration and web.xml
, and in that case, you can consider the DispatcherServletInitializer
class as similar to web.xml
. In step 2, we configured a servlet of type DispatcherServlet
by extending the AbstractAnnotationConfigDispatcherServletInitializer
class, which is more or less similar to any other normal servlet configuration. The only difference is that we have not instantiated the DispatcherServlet
class for that configuration. Instead, the servlet class (org.springframework.web.servlet.DispatcherServlet
) is provided by the Spring MVC framework and we initialized it using the AbstractAnnotationConfigDispatcherServletInitializer
class.
After this step, our configured DispatcherServlet
will be ready to handle any requests that come to our application on runtime and will dispatch the request to the correct controller's method.
However, DispatcherServlet
should know how to access the controller instances and view files that are located in our project, and only then can it properly dispatch the request to the correct controllers. So we have to give some hint to DispatcherServlet
to locate the controller instances and view files.
This is what we configured within the getServletConfigClasses
method of the DispatcherServletInitializer
class. By overriding the getServletConfigClasses
method, we are telling DispatcherServlet
about our controller classes and view files. And in step 1, through the WebApplicationContextConfig
class file, we configured the InternalResourceViewResolver
and other default configurations.
Don't worry if you are not able to understand each and every configuration in the WebApplicationContextConfig
and DispatcherServletInitializer
classes; we will take a look deep into these configuration files in next chapter. As of now, just remember that this is a one-time configuration that is needed to run our project successfully.