Tutorial

Spring MVC Tutorial

Published on August 3, 2022
Default avatar

By Pankaj

Spring MVC Tutorial

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

In this Spring MVC Tutorial, we will learn how to develop Spring MVC web application using Spring Tool Suite. Spring MVC framework is widely used for java web applications.

Spring MVC

spring mvc, spring mvc tutorial Just like Struts Framework, Spring MVC is also based on Java EE Servlet and JSP technologies and implement Model-View-Controller design pattern.

Spring MVC Tutorial

We have earlier seen how Spring Dependency Injection works and in this tutorial we will learn how to create a simple web application using Spring MVC framework. We can use Eclipse or IntelliJ IDE for the Spring projects development, but SpringSource provides Spring Tool Suite (STS) that is an IDE based on Eclipse and comes with in-built VMware vFabric tc Server that is built on top of Apache Tomcat container and optimised for Spring-based applications. I would use STS for Spring MVC tutorial and other future tutorials because it makes a developer life easier by providing the following features:

  • Support for creating skeletal Spring applications (MVC, Rest, Batch etc), good for starting the project from scratch. We will soon see in this spring MVC tutorial how easy it is to create a Spring MVC project.
  • Provides useful features such as creating Spring Configuration files, parsing config files and classes to provide useful information about them.
  • Automatic validation of Spring application
  • Refactoring support to easily make project changes, the changes get reflected in config files too.
  • Code assist for not only classes but configuration files too, I like this feature a lot because most of the times we need to know what we can use and its details.
  • Best support for Aspect Oriented Programming (AOP) through the integration of AspectJ.

Looking at all the features STS provide, I was sold for this and decided to use it for Spring application and till now I am very happy with it. Just Download the STS from STS Official Download Page and install it. I am using STS 3.4.0.RELEASE that is based on Eclipse 4.3.1 release. Spring Tool Suite, Spring MVC, Spring MVC Tutorial for beginners If you don’t want to use STS and want to get its facilities in existing Eclipse, then you need to install its plugin from Eclipse Marketplace. Use below image as a reference and make sure to chose the correct STS version for installation. Below plugin is good for Eclipse Kepler. Spring Tool Suite, Spring MVC, Spring MVC Tutorial Eclipse If you don’t want to use SpringSource server, you can deploy the application in any other Java EE container such as Tomcat, JBoss etc. For this tutorial, I will use the server that ships with STS but I have tested the application by exporting it as WAR file into separate tomcat server and it’s working fine. Now that our server environment and IDE is ready, let’s proceed to create our first Spring MVC project. Below steps are valid for STS as well as Eclipse with STS plugins.

Creating Spring MVC Application in STS or Eclipse

Step 1: Create New Spring Project from the menu. Spring MVC, Spring MVC Project, Spring MVC Example Step 2: In the new project window, give the name as “SpringMVCExample” and chose template as “Spring MVC Project”. If you are using this template for the first time, STS will download it from SpringSource website. If you want, you can add the project to any working set. Spring MVC Spring MVC Template Download, Spring MVC Project, Spring MVC Example Step 3: When the template is downloaded, in the next screen you need to provide the top-level package name. This package will be used as the base-package for Spring components. Spring MVC source Package, Spring MVC, Spring MVC Example, Spring MVC Tutorial Step 4: Once the project is created by Spring MVC template, it will look like below image. Spring MVC Don’t worry if you don’t see User.java class, login.jsp and user.jsp files, they have been added by me later on. If your project is not compiled and you see some errors, run Maven/Update Project. Make sure to check the “Force update of Snapshots/Releases” options, refer below image. Spring MVC, Maven Force update projects Overall project looks just like any other maven based web application with some Spring configuration files. Now it’s time to analyze the different part of the projects and extend it a little.

Spring MVC Dependencies

Our generated pom.xml file looks like below.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.journaldev</groupId>
	<artifactId>SpringMVCExample</artifactId>
	<name>SpringMVCExample</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.6</java-version>
		<org.springframework-version>4.0.0.RELEASE</org.springframework-version>
		<org.aspectj-version>1.7.4</org.aspectj-version>
		<org.slf4j-version>1.7.5</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	
		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>        
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

artifactId will be the servlet-context for the web application, so you can change it if you want something else. There are few properties defined for Spring Framework, AspectJ and SLF4j versions, I found that they were not reflecting the latest versions, so I have changed them to the latest stable version as of today. The project dependencies that I am interested in are;

  • spring-context: Spring Core dependency. Notice the exclusion of commons logging in favor of SLF4J.
  • spring-webmvc: Spring artifact for MVC support
  • aspectjrt: AspectJ API reference
  • SLF4J and Log4j: For logging purposes, Spring is very easy to configure for log4j or Java Logging API because of SLF4J integration.
  • javax.inject - JSR330 API for dependency injection

There are some other dependencies added, such as Servlet, JSP, JSTL and JUnit API but for starter application, we can overlook them.

Spring MVC Tutorial - Log4j Configuration

The generated log4j.xml file looks like below.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="com.journaldev.spring">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="console" />
	</root>
	
</log4j:configuration>

Notice that it’s printing everything to console, we can easily add appenders to redirect logging to files.

Spring MVC Tutorial - Deployment Descriptor Configuration

Let’s see our web.xml and analyze it.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

ContextLoaderListener ties the ApplicationContext lifecycle to ServletContext lifecycle and automate the creation of ApplicationContext. ApplicationContext is the place for Spring beans and we can provide it’s configuration through contextConfigLocation context parameter. root-context.xml file provides the configuration details for WebApplicationContext. DispatcherServlet is the controller class for Spring MVC application and all the client requests are getting handled by this servlet. The configuration is being loaded from the servlet-context.xml file.

Spring MVC Tutorial - Configuration Files

root-context.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
</beans>

We can define shared beans here, as of now there is nothing in it. servlet-context.xml code:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		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">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.journaldev.spring" />	
	
</beans:beans>

This is how the standard Spring configuration file looks like, just imagine writing all this on your own and you will start liking STS tool. annotation-driven element is used to let Controller servlet know that annotations will be used for bean configurations. resources element defines the location where we can put static files such as images, HTML pages etc that we don’t want to get through Spring framework. InternalResourceViewResolver is the view resolver, we can provide view pages location through prefix and suffix properties. So all our JSP pages should be in /WEB-INF/views/ directory. context:component-scan element is used to provide the base-package location for scanning Controller classes. Remember the value of the top-level package given at the time of project creation, it’s the same value getting used here.

Spring MVC Controller Class

HomeController is created automatically with the home() method, although I have extended it a little bit by adding loginPage() and login() methods.

package com.journaldev.spring;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String loginPage(Locale locale, Model model) {
		return "login";
	}
	
	@RequestMapping(value = "/home", method = RequestMethod.POST)
	public String login(@Validated User user, Model model) {
		model.addAttribute("userName", user.getUserName());
		return "user";
	}
}

@Controller annotation is used to indicate that it’s a web controller class. @RequestMapping is used with classes and methods to redirect the client request to specific handler method. Notice that handler methods are returning String, this should be the name of view page to be used as the response. As you can see that we are having three methods returning different strings, so we need to create JSP pages with the same name. Notice that login() method will get called with HTTP method as POST, so we are expecting some form data here. So we have User model class and it’s marked for validation using @Validated annotation. Every method contains Model as an argument and we can set attributes to be later used in the JSP response pages.

Spring MVC Model Classes

Model classes are used to hold form variables, our User model bean looks like below.

package com.journaldev.spring;

public class User {

	private String userName;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}

A simple java bean with the variable name and its getter and setter methods.

Spring MVC Tutorial - View Pages

We have three JSP pages like below. home.jsp code:

<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

Notice the use of JSP Expression Language to get the attribute values. login.jsp code:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
</head>
<body>
<form action="home" method="post">
<input type="text" name="userName"><br>
<input type="submit" value="Login">
</form>
</body>
</html>

A simple JSP page for the user to provide the userName as input. Notice that form variable name is same as User class variable name. Also, form action is “home” and method is “post”. It’s clear that HomeController login() method will handle this request. user.jsp code:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Home Page</title>
</head>
<body>
<h3>Hi ${userName}</h3>
</body>
</html>

Simple home page for the user where username is displayed, notice that we are setting this attribute in the login method.

Spring MVC Example Application Testing

Our application is ready for execution, just run it on the VMware tc Server or your choice of any other servlet container, you will get below pages as the response. Spring MVC Hello World, Spring MVC, Spring MVC Example Spring MVC Hello World, Spring MVC Spring MVC Hello World, Spring MVC Tutorial That’s it for Spring MVC Tutorial, you can see that how easy it is to create Spring MVC application using STS plugins. The code size is very less and most of the configuration is handled by Spring MVC so that we can focus on business logic. Download the example spring MVC project from below link and play around with it.

Download Spring MVC Project

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Pankaj

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
January 27, 2021

Is it possible to deploy above application as > Web Server Application Server DB server. If possible , how ?

- Rahul

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    May 10, 2020

    How do you incorporate security into this model

    - Mac

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      March 6, 2020

      how to store jdbc sessions in spring mvc (xml based configurations) please help us

      - madhusudhan

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        January 10, 2020

        Hello sir, can you please explain me how the private Strings are able to hold the data given from the JSP input field?

        - Abishek Dinesh

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          April 30, 2019

          Hi Pankaj, Thanks a lot for your awesome content. I am facing one issue though while following this tutorial, While I am deploying the application from the STS itself then it’s not returning me any content for the URL ping: https://localhost:8080/demo/ But if I put the war file generated in the tomcat webapps directory and run the tomcat from the outside of STS by running startup.bat file and then ping the above URL then it works fine. Please let me know the reason behind this. Thanks, Krutik

          - Krutik

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            March 20, 2019

            Every thing is easy to understand…Thanks for knowledge sharing…it works well …

            - ram

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              February 11, 2019

              Just followed the tutorial as it is on STS-Java 8 I got “https://localhost:8080/spring/” running and showing results as: Hello world! The time on the server is 11 February 2019 10:07:37 PM IST. but https://localhost:8080/SpringMVCExample/login doesn’t work… I get 404 error… there looks to be some issue with the context configurations. please help… HTTP Status 404 – Not Found --------------------------------------------------------------------------------

              - Ankush Khandelwal

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                December 13, 2018

                If I wanna create MVC project in IntelliJ what should I do?

                - parsa

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  November 3, 2018

                  Is there something wrong in the context? It is giving me 404 error. I checked the war file name being created (SpringMVCExample-1.0.0-BUILD-SNAPSHOT) and add that to context in the browser. I.e https://localhost:8080/SpringMVCExample-1.0.0-BUILD-SNAPSHOT/ and it still gave me 404 error. Could you please check?

                  - DJ

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    October 16, 2018

                    i imported the downloaded zip file in STS and then selected run on server and then this error comes. what is this WAR file you keep on talking about i dont see any WAR file here ? do i have to export this project ? or something ? I get the same error in the spring rest api tutorial when i download and import the project in STS. HTTP Status 404 – Not Found -------------------------------------------------------------------------------- Type Status Report Message /SpringMVCExample/ Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

                    - subarashi

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Get our biweekly newsletter

                      Sign up for Infrastructure as a Newsletter.

                      Hollie's Hub for Good

                      Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

                      Become a contributor

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      Welcome to the developer cloud

                      DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Learn more
                      DigitalOcean Cloud Control Panel