Sunday, December 17, 2023

How to enable Spring MVC in Java Web Application? Example Tutorial

In last article, I have shared thoughts on how to enable Spring Security on Java Web application, where my reader also shown interest to know how to configure/enable Spring MVC in Java web application. Though, this is very basic information, it helps a lot to anyone who is new to String framework and want to understand then essential steps required to enable Spring MVC framework for a Java based web application. It's easy to configure Spring MVC if you have developed a simple hello word kind of program using Servlet or JSP and familiar with web application fundamentals in Java world e.g. Servlet container like Tomcat, deployment descriptor file or web.xml, Servlet or JSP itself and some essential tags on web.xml e.g. <servlet> and <servlet-mapping>, <url-pattern> etc. 

At the very least you need to declare DispatcherServlet in the web.xml to enable Spring MVC in your Java based web application. Many places say that you also need ContextLoaderListener but that is optional. 

You can have it if you want but for simplest of application you can declare all your beans in the spring configuration file used by DispatcherServlet e.g. controllers, view resolvers and handler mappings. 

The DispatcherServlet is usually pre-loaded in Java based web application by using  the <load-on-startup> tag of deployment descriptor. 

A positive value for this tag ensures that servlet container will load the Servlet when the web application is deployed and context is created, rather than when a request arrived for that Servlet, which is actually the default time to initialize a Servlet in a Java based web application. 

When DispatcherServlet is loaded by Servlet container, it by default looks for a file named servlet-name-servlet.xml, where servlet-name is the value of <servlet-name> in the web.xml. 

For example, if you give the DispatcherServlet name as "dispatcher" as shown in our web.xml in next section then it will look for a file called "dispatcher-servlet.xml" in the /WEB-INF directory to load web specific Spring beans e.g. spring mvc controllers, view resolvers and handler mappings. 

Though, you can also override the default location by providing a parameter contextConfigLocation to the servlet, but default will do for our sample web application. 

The DispatcherServlet then create and initialize the Spring beans declared in this file and they are stored at WebApplicationContext, which is the web specific version of ApplicationContext. The application context is the place where Spring bean lives. 

If you need any spring bean, then you get it from the ApplicationContext, but usually it is automatically wired to the classes which declared them as dependency, in fact, this is the biggest advantage of using Spring framework for developing Java application. 

web.xml configuration to enable Spring MVC

Here is the sample web.xml configuration to enable Spring MVC in Java based web applications:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" 
xmlns="https://java.sun.com/xml/ns/javaee" 
xmlns:web="https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="
https://java.sun.com/xml/ns/javaee 
https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
id="WebApp_ID" 
version="2.5">
<display-name>Hello Spring MVC</display-name>
<welcome-file-list> 
<welcome-file>index.jsp</welcome-file> 
</welcome-file-list>

<servlet>
  <servlet-name>dispatcher</servlet-name>
   <servlet-class>
     org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*</url-pattern>
  </servlet-mapping>
</web-app>

You also need to create a file called dispatcher-servlet.xml because you have given <servlet-name>dispatcher</servlet-name> and put it in the WEB-INF directory. 

This file will contain Spring beans required by your web application e.g. controllers, view resolvers and handler mappings. 

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="https://www.springframework.org/schema/beans"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="https://www.springframework.org/schema/p"
	xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="
https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd 
https://www.springframework.org/schema/context 
https://www.springframework.org/schema/context/spring-context.xsd">
	<bean id="bean1">
...
</bean>
	<bean id="bean2">
...
</bean>
	<context:component-scan base-package="com.example" />
	<!-- View Resolver -->
	<bean 
id="viewResolver" 
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property 
name="viewClass" 
value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

Since component-scan is enabled it will find all Controllers any class annotated with @Controller annotation and create beans in application context. That's all you need to enable Spring MVC in your Java based web application. 

Some of you may be asking whether its a good idea to define beans in dispatcher-servlet.xml than applicationContext.xml? Well, usually it's better to distribute the beans by layers of your application. 

Beans for the presentation layer (for example mvc controllers and view resolvers ) can be in dispatcher-servlet.xml. Beans belonging to the service layer and DAO layer should be defined applicationContext.xml. It's not a strict rule, but it's a good practice to achieve separation of concern.

In Spring MVC, ContextLoaderListener is used to load beans which are not web specific and shared between multiple DispatcherServlet. Yes, Spring MVC also allows to configure more than one DispatcherServlet. 

In general you have two application context in any Spring MVC application, the root context created by ContextLoaderListener and web-context created by DispatcherServlet. 

All the beans belonging to web layer is defined in the configuration file loaded by DispatcherServlet i.e. dispatcher-servlet.xml and they live on the context created by DispatcherServlet, while all beans belongs to service and DAO layer goes to the applicationContext.xml loaded by ContextLoaderListener.




If you want to use ContextLoaderListener in your Spring MVC application then you need to add following configuration in your web.xml:

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
	<param-name>contextClass</param-name>
	<param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
       </param-value>
</context-param>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>example.config.AppConfig</param-value>
</context-param>

Both contextClass and contextConfigLocation is optional and if you don't define then by default Spring will use XmlWebApplicationContext and the default location and configuration file will be "/WEB-INF/applicationContext.xml". 

If you have multiple spring configuration file, its better you specify all of them using contextConfigLocation parameter e.g. e.g. "WEB-INF/applicationContext1.xml, WEB-INF/applicationContext2.xml".

 It also support Ant-style path patterns e.g. "WEB-INF/*Context.xml,WEB-INF/spring*.xml" or "WEB-INF/**/*Context.xml".

Btw, this is not the only way to enable Spring MVC in your Java based web application. You can also configure Spring MVC without making any change in your web.xml e.g. by using annotation and @EnableWebMVC annotation of Spring 3.1, which greatly simplify the configuration of Spring MVC. 


Enabling Spring MVC using @EnableWebMVC Annotation

Historically, Spring MVC has been configured using XML but there is also a <mvc:annotation-driven> you can enable annotation-driven Spring MVC. This Spring MVC namespace tag is equal to using @EnableWebMVC annotation , which provides the simplest Spring configuration. 

All you need a class annotated using @EnableWebMvc to enable Spring MVC in Java based application as shown below:

@Configuration
@EnableWebMvc
public class WebConfig{

}

This will work and it will enable Spring MVC but it leaves a lot to be desired e.g. no view resolver is configured, component scanning is not enabled, which means only controllers declared in configuration will be found, and DispatcherServlet is mapped as the default servlet for the application and it will handle all requests, including request for static resources, such as images and css, which is probably not you want in many cases.

By default Spring will use BeanNameViewReesolvers, which will resolves views by looking for beans whose ID matches the view name and the class implements View interface. See Spring in Action 4th Edition for more details on using @EnableWebMvc annotation to enable Spring MVC application. 

That's all about how to enable Spring MVC in Java based web application. You can see that at bare minimum you just need to hook DispatcherServlet in your deployment descriptor and need to provide a spring configuration file e.g. dispatcher-servlet.xml which is basically the [servlet-name]-servlet.xml and contains web specific beans e.g. controllers, view resolvers and handler mappings. 

The ContextLoaderListener is optional but if you want to create root context and want to load beans from service and dao layers then you can also declare it on the web.xml file.

Finally, you can also use @EnableWebMvc annotation to enable Spring MVC in Java based web application programmatically using annotation. It is equivalent to <mvc:annotation-driven> tag from Spring MVC namespace. 

Other Java and Spring articles you may like
  • 5 Spring Boot Features Every Java Developer Should Know (features)
  • How to test Spring boot application in Java? (spring boot testing example)
  • Spring Boot + ThyMyleaf project example (thymyleaf example)
  • 10 Tools Java Developers use in their day-to-day life (tools)
  • 15 Spring Boot Interview Questions for Java Programmers (questions)
  • Spring Boot Integration test example (integration test example)
  • 3 Best Practices Java Programmers can learn from Spring (best practices)
  • How to post JSON data using Postman? (postman json example)
  • 10 Spring Core Annotations Java Developers should learn (annotations)
  • 3 ways to change Tomcat port in Spring Boot (tutorial)
  • 5 courses to learn Spring Boot and Spring Cloud( courses)
  • Top 5 Free Courses to learn Spring and Spring Boot (courses)
  • 5 Courses to Master Spring Boot online(courses)
  • 7 Courses to learn Microservices for Java developers (courses)
  • 10 Spring MVC annotations Java developers should learn (annotations)
  • 10 Advanced Spring Courses for Experienced Programmers (courses)


Thanks for reading this article so far. If you like this article then please share with your friends and colleagues. If you have any question or feedback, then please drop a comment and I'll try to find an answer for you. 

1 comment :

Anonymous said...

I only use Java configuration now a days but thanks for sharing XML configuration, I totally forgotten that.

Post a Comment