Spring MVC Tutorial: Web Application Guide With Examples

Spring MVC Web Application Tutorial With Examples

Part 1

The purpose of this Spring MVC tutorial is to build a web-application utilizing the Spring MVC framework (which is one of the most popular and best Java web frameworks around), including real world examples. This tutorial will be presented in multiple parts with each subsequent part building in more functionality such as using a Relational Database or adding use of Spring Security for authentication and authorization.

The web-application we will be building is a Purchase Request Application. Some companies requires employees to submit purchase request forms in order to get approval for any company expenses/purchases. The approval process goes through several approvers for whom can approve or deny the request.

A denied request can include a message from the approver on the reason for the denial which may allow the submitter the ability to make any adjustments for resubmission.  We will be making this process available as a web-application.

Part 1 will demonstrate how to setup a basic Spring MVC project, create a Spring Controller, Service Layer spring components, and create a JSP template file to render the page.

Environment Details

  • JDK 1.7
  • Apache Tomcat 7
  • Maven 3.x
  • Ubuntu

Spring MVC Tutorial: Setting up Tomcat

What is Tomcat?

Apache Tomcat is an open-source web server and servlet container for rendering Java Server Pages (JSPs) and executing servlets. Web applications can be deployed to a Tomcat server using WAR files (Java web archive files). Tomcat does not support the full EE stack and will not deploy EAR files.

If you don’t have a place to run your Tomcat yet, you can check out JavaPipe’s Java web hosting offers and see if that’s what you’re looking for. For now let’s proceed on how to setup your own Tomcat container.

Installing Tomcat

  1. Download the core tar.gz file from  http://tomcat.apache.org/download-70.cgi
  2. Extract tar.gz file and copy to desired directory.
 tar -xvf apache-tomcat-7x.tar.gz

The directory used for this tutorial is the /opt directory but you can use any directory as long as it has read and write privileges for your user.

Running Tomcat

  1. Go to /opt/apache-tomcat-7.x/bin and execute startup.sh file.
  2. Verify application server is running by going to localhost:8080/ and you should see this page:

Spring MVC Tutorial

Spring MVC Tutorial: Set Up the Project

This section of the article focuses on creating the file structure and configuration files required for this Spring application.

Create the Spring project folder

Create a PurchaseRequestApp folder, in this case it was created under /home/alux/Projects but it can be put in any directory as long as you have read and write permission.

mkdir /home/alux/Projects/PurchaseRequestApp

Create the folder structure

Create the following folder structure under the project folder (PurchaseRequestApp)

Spring MVC Example

Create a maven build file (pom.xml) at the root of the project folder. The first dependency is spring-context which provides core Spring functionality including dependency injection. The Spring MVC framework provides HTTP integration including an implementation of Spring MVC. The jstl artifact is required to be able to use jstl on JSP pages.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  
http://maven.apache.org/xsd/maven-4.0.0.xsd" >               
<modelVersion>4.0.0</modelVersion>               
<groupId>PurchaseRequestApp</groupId>               
<artifactId>PurchaseRequestApp</artifactId>               
<version>1</version>               
<packaging>war</packaging>                
<dependencies>                   
<dependency>                       
<groupId>org.springframework</groupId>                       
<artifactId>spring-context</artifactId>                       
<version>4.1.1.RELEASE</version>                   
</dependency>           
        
<dependency>                       
<groupId>org.springframework</groupId>                       
<artifactId>spring-webmvc</artifactId>                       
<version>4.1.1.RELEASE</version>                   
</dependency>                   
<dependency>                       
<groupId>javax.servlet</groupId>                       
<artifactId>jstl</artifactId>                       
<version>1.2</version>                   
</dependency>               
</dependencies>               

<build>                   
<finalName>backoffice</finalName> 
<!--Sets the war file name to backoffice-->                   
<plugins>                       
<plugin>                           
<artifactId>maven-compiler-plugin</artifactId>                           
<version>3.1</version>                           
<configuration>                               
<source>1.7</source>                               
<target>1.7</target>                           
</configuration>                       
</plugin>                      
<plugin>                           
<artifactId>maven-war-plugin</artifactId>                           
<version>2.4</version>                       
</plugin>                   
</plugins>               
</build>           
</project>

Deployment descriptor file (web.xml).

The deployment descriptor is used by Java web applications to determine how URLs are mapped to servlets. At this point all that is needed is to map Spring’s DispatcherServlet.

The DispatcherServlet is responsible for invoking the correct handlers (for this application it will be a Controller) based on the incoming request URI.

/webapp/WEB-INF/web.xml

 <?xml version="1.0" encoding="UTF-8"?>                   <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns="http://java.sun.com/xml/ns/javaee"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  version="3.0">           <servlet>               <servlet-name>mvc-dispatcher</servlet-name>                   <servlet-class>                        org.springframework.web.servlet.DispatcherServlet                   </servlet-class>                   <load-on-startup>1</load-on-startup>             </servlet>                        <servlet-mapping>               <servlet-name>mvc-dispatcher</servlet-name>                   <url-pattern>/</url-pattern>             </servlet-mapping>                      </web-app>

Spring MVC Example Configuration File: mvc-dispatcher-servlet.xml

This file contains Spring Bean definitions and other Spring Context information.By default Spring looks for a application context configuration file /WEB-INF/${servlet-name}-servlet.xml for servlets defined in web.xml. The first thing required for this file will be the <context:component-scan base-package=”com.addolux”/> line which tells the application to look through the all the classes under com.addolux for Spring bean component annotations such as @Component or @Controller (which will be implemented later) and add them to the application context. Next a ViewResolver bean must be configured so that the views returned by controllers and be resolved to a JSP.

/webapp/WEB-INF/mvc-dispatcher-servlet.xml

   <?xml version="1.0" encoding="UTF-8"?>     <beans xmlns="http://www.springframework.org/schema/beans"                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                  xmlns:p="http://www.springframework.org/schema/p"                  xmlns:context="http://www.springframework.org/schema/context"                  xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                  http://www.springframework.org/schema/context                 http://www.springframework.org/schema/context/spring-context-4.0.xsd">               <context:component-scan base-package="com.addolux" />               <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>

Create the PurchaseRequestDTO and Service Classes

At this point there is no persistence configured for this application and the service class will return dummy DTO data.

com.addolux.purchaserequest.dto.PurchaseRequestDTO

 package com.addolux.purchaserequest.dto;                      public class PurchaseRequestDTO {               private String poNumber;               private String date;               private String justification;               public String getPoNumber() {                   return poNumber;               }               public void setPoNumber(String poNumber) {                   this.poNumber = poNumber;               }               public String getDate() {                   return date;               }               public void setDate(String date) {                   this.date = date;               }               public String getJustification() {                   return justification;               }               public void setJustification(String justification) {                   this.justification = justification;               }           }

com.addolux.purchaserequest.service.PurchaseRequestService

 package com.addolux.purchaserequest.service;   import com.addolux.purchaserequest.dto.PurchaseRequestDTO;   import java.util.List;              public interface PurchaseRequestService {      public List<PurchaseRequestDTO> getAllPurchaseRequests();   }

com.addolux.purchaserequest.sevice.impl.PurchaseRequestServiceImpl

 package com.addolux.purchaserequest.service.impl;              import com.addolux.purchaserequest.dto.PurchaseRequestDTO;   import com.addolux.purchaserequest.service.PurchaseRequestService;   import java.util.ArrayList;   import java.util.List;   public class PurchaseRequestServiceImpl implements PurchaseRequestService{       @Override       public List<PurchaseRequestDTO> getAllPurchaseRequests() {           return getDummyPurchaseRequestData();       }                       private List<PurchaseRequestDTO> getDummyPurchaseRequestData(){           List<PurchaseRequestDTO> purchaseRequestDTOs = new ArrayList<PurchaseRequestDTO>();                           //Create dummy data here                         return purchaseRequestDTOs;         }   }

Add the service class to application context

To make the PurchaseRequestServiceImpl a Spring bean component it must be configured either through xml or annotations. For this application service layer components are configured through xml to centralize the configuration details though this can also be done by adding @Component to the classes.

Add the following line to mvc-dispatcher-servlet.xml just before the beans closing tag:

mvc-dispatcher-servlet.xml

 <bean id="purchaseRequestService" class="com.addolux.purchaserequest.service.impl.PurchaseRequestServiceImpl"/>

Create the view

Wireframes

spring mvc tutorial

JSP (JavaServer Pages)

I have utilized a front-end framework Bootstrap to add styling to the page. See  http://getbootstrap.com  for more information.

/webapp/WEB-INF/jsp/myRequests.jsp

 <!DOCTYPE html>           <html lang="en">           <head>               <title>Purchase Requests</title>               <meta name="viewport" content="width=device-width, initial-scale=1">               <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" >               <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js" ></script>               <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" ></script>               <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>               <jsp:useBean id="myRequestList" scope="request" type="java.util.List"/>           </head>           <body>           <div class="container-fluid">               <div class="page-header">                   <h1>Purchase Requests</h1>               </div>               <div class="row">                   <ul class="nav nav-tabs">                       <li role="presentation" class="active"><a href="#">Saved</a></li>                       <li role="presentation"><a href="#">Submitted</a></li>                       <li role="presentation"><a href="#">Approved</a></li>                   </ul>               </div>               <div class="row">                   <table class="table">                       <thead>                       <tr>                           <th>PO Number</th>                           <th>Date</th>                           <th>Justification</th>                       </tr>                       </thead>                       <tbody>                           <c:forEach items="${myRequestList}" var="request">                               <tr>                                   <td>${request.poNumber}</td>                                   <td>${request.date}</td>                                   <td>${request.justification}</td>                               </tr>                           </c:forEach>                       </tbody>                   </table>               </div>           </div>           </body>           </html>

Create the Controller

To render the jsp page using dynamic PurchaseRequestData a Controller class is implemented. For the PurchaseRequestController to be able to handle requests the annotations @Controller and @RequestMapping are required. The @Controller annotation configures the class as a Spring component intended to handle HttpRequests and @RequestMapping maps the request URI to specific handler methods and classes.

To be able to handle a GET request for ${domain name}/purchase-request/myRequests the appropriate @RequestMapping values need to be added to the class and the method responsible for handling the request. The PurchaseRequestServiceImpl component can be injected by using @Resource which will by default look for a component named purchaseRequestService (which was done in previous steps).

com.addolux.purchaserequest.controller.PurchaseRequestController

 package com.addolux.purchaserequest.controller;                      import com.addolux.purchaserequest.service.PurchaseRequestService;           import org.springframework.stereotype.Controller;           import org.springframework.ui.Model;           import org.springframework.web.bind.annotation.RequestMapping;           import org.springframework.web.bind.annotation.RequestMethod;           import javax.annotation.Resource;                      @Controller           @RequestMapping("/purchase-request")           public class PurchaseRequestController {                               private static final String MY_REQUESTS_VIEW="myRequests";               private static final String MY_REQUESTS_MODEL_ATTRIBUTE="myRequestList";                               @Resource               private PurchaseRequestService purchaseRequestService;                               @RequestMapping(value = "/myRequests", method = RequestMethod.GET)               public String getMyRequests(Model model){                   model.addAttribute(MY_REQUESTS_MODEL_ATTRIBUTE, purchaseRequestService.getAllPurchaseRequests());                   return MY_REQUESTS_VIEW;               }           }

Spring MVC Example: Completed Project File Structure

spring mvc example

Spring MVC Tutorial: Build and Deploy the Application

To package the project into a war file go to the root of the project directory (where the pom.xml file is) and run the package command:

 mvn clean package

This will create a war file under the target folder. To deploy this application copy the war file into Tomcat’s webapps folder.

 cp backoffice.war /opt/apache-tomcat-7.0.63/webapps/

View the Spring MVC Example Application

By default the context path of the application is the name of the war file so for the above war file the purchase requests page would be located at http://localhost:8080/backoffice/purchase-request/myRequests

Spring framework framework app

Summary

We have setup a Spring MVC application project from scratch developing the necessary configurations, Java classes, and JSP pages. We set up hosting for the Spring MVC framework to make our application available online. We have even demonstrated how to add model data from within the controller so that it would be available to our JSP. In the next part of our Spring MVC tutorial series we will be wiring the application to a relational database so that the same model data can added and retrieved from the database.

Part 2

In this tutorial, I will show how to connect the Spring MVC application created in part 1 to a relational database (MySQL) and use Spring Data repositories and hibernate to save and retrieve data from the database.

This uses an older version of Spring to keep consistent with part 1 but the concepts are still applicable to newer versions of Spring. In particular, the XML based configuration is something that I have seen the Spring community move away from and towards Java based configurations.

In the next part of this series, I will migrate this application to Spring Boot and use the latest stable versions of everything. Also, I intentionally doing things like packaging the application and manually moving it to Tomcat so you can get an idea of how things work.

In a real Java development environment, you would want to automate these steps using a maven plugin to package a war file before uploading to your tomcat webapps directory.

If you use Spring Boot you don’t have to worry about this at all as it has its own embedded application server, but I will go into more detail about that in part 3.

The first step will be to update the pom.xml file to update the Spring version by updating the below property.

<springframework.version>4.3.22.RELEASE</springframework.version>

The next step will be to add the necessary Hibernate, JPA, and MySQL connector dependencies. I will just give a quick overview of what these are.

Spring Data: From Spring’s website “Spring Data] is an umbrella project which contains many sub projects that are specific to a given database”. Basically, it provides modules that allow your Spring application to interact with data access technologies in a consistent way using the Repository abstraction.

This could be relational, NoSQL, or even search engines like Solr. I am going to use the JPA module to interact with a MySQL database for this tutorial. JPA itself is just a specification, we will need to use an implementation of that specification and I am going to use Hibernate since that is the most widely used.

We will also need the drivers to allow Java to communicate with the database.

<!--Hibernate--> <dependency>    <groupId>org.hibernate</groupId>    <artifactId>hibernate-core</artifactId>    <version>5.2.2.Final</version> </dependency>  <dependency>    <groupId>org.hibernate</groupId>    <artifactId>hibernate-entitymanager</artifactId>    <version>5.2.2.Final</version> </dependency> <dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>5.1.47</version> </dependency> <!--JPA --> <dependency>    <groupId>org.springframework.data</groupId>    <artifactId>spring-data-jpa</artifactId>    <version>1.7.4.RELEASE</version> </dependency>
Next we will setup the database connection information for the application. Create an XML file called data-config.xml with the following content:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">        <property name="driverClassName" value="com.mysql.jdbc.Driver" />        <property name="url" value="jdbc:mysql://localhost:3306/my_db" />        <property name="username" value="myuser" />        <property name="password" value="password" />    </bean>    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        <property name="dataSource" ref="dataSource"/>        <property name="packagesToScan" value="com.addolux.purchaserequest.dto"/>        <property name='jpaVendorAdapter' ref="jpaVendorAdapter"/>        <!-- Set JPA properties -->        <property name="jpaProperties">            <props>                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>            </props>        </property>    </bean>    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">        <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>    </bean>     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">        <property name="entityManagerFactory" ref="entityManagerFactory" />    </bean>  </beans>
This sets up the beans needed for accessing data. Next, I will create a Spring repository for persisting and retrieving data. Create a repository directory and add a class called PurchaseRequestRepository:
package com.addolux.purchaserequest.repository;  import com.addolux.purchaserequest.dto.PurchaseRequestDTO; import org.springframework.data.repository.CrudRepository;  public interface PurchaseRequestRepository extends CrudRepository<PurchaseRequestDTO,Long> { }
This is all we need to get crud functionality for the PurchaseRequestDTO. Under the hood, Spring will create all the boilerplate code but before that I need to tell Spring where to look for Repositories. That is done by adding this line to the data-config.xml file created earlier:
<jpa:repositories base-package="com.addolux.purchaserequest.repository"/>
You will also want to include the following line to the spring-mvc-dispatchter.xml file so that Spring is aware of this configuration file:
<import resource="data-config.xml"/>
Now to make our PurchaseRequestDTO into a JPA entity (not showing setters and getters):
package com.addolux.purchaserequest.dto; import javax.persistence.*; import java.time.LocalDate; @Entity @Table(name = "purchase_requests") public class PurchaseRequestDTO {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    @Column    private String poNumber;    @Column(name = "requestDate")    private LocalDate date;    @Column    private String justification;
The @Entity annotation tells Spring that this object is going to be mapped to the database and the @Table annotation tells it which table. To be able to persist this object it needs an @Id annotated field.

I also need to tell Spring that this value is going to be generated by the database. The columns will automatically match the properties if they have the same name but you can also specify what the name should be.

That is all we need to do for the JPA/Hibernate part. Now we can inject the PurchaseRequestRepository into the PurchaseRequestServiceImpl so we can display real data:

public class PurchaseRequestServiceImpl implements PurchaseRequestService {    @Autowired    private PurchaseRequestRepository purchaseRequestRepository;    @Override    public List<PurchaseRequestDTO> getAllPurchaseRequests() {        if (purchaseRequestRepository.count() == 0 ) {            PurchaseRequestDTO purchaseRequestDTO1 = new PurchaseRequestDTO();            purchaseRequestDTO1.setJustification("Justification 1");            purchaseRequestDTO1.setDate(LocalDate.now());            purchaseRequestDTO1.setPoNumber("1234");            purchaseRequestRepository.save(purchaseRequestDTO1);            PurchaseRequestDTO purchaseRequestDTO2 = new PurchaseRequestDTO();            purchaseRequestDTO2.setJustification("Justification 2");            purchaseRequestDTO2.setDate(LocalDate.now().minusDays(2));            purchaseRequestDTO2.setPoNumber("5678");            purchaseRequestRepository.save(purchaseRequestDTO2);        }        return (List<PurchaseRequestDTO>) purchaseRequestRepository.findAll();    } }
This will write 2 PurchaseRequests to the database and then return everything that has been persisted. Now after building and deploying the application, you can see that this data is being displayed on the front-end. Spring MVC examples tutorial screenshot That That was an overview of configuring some basic persistence functionality provided by Spring Data and Hibernate. Something to keep in mind is that in simple cases like this with one table ORM’s like Hibernate are very easy to use but as the number of tables and general complexity of your data model increases they can become much more difficult to work with.

In this case, you could use a Java framework like QueryDsl or JOOQ to build complex queries programmatically or look into the Spring Data JDBC module which is a much simpler ORM.

Share this post

Share on facebook
Share on twitter
Share on linkedin
Share on reddit
Share on skype
Share on telegram
Share on whatsapp

3 thoughts on “Spring MVC Web Application Tutorial With Examples”

  1. Lawrence Macharia

    Hello,

    Great article especially for a beginner like me. Good work!!

    Did you publish part 2?

Leave a Comment

Your email address will not be published. Required fields are marked *

Take Your Java App to the Cloud

Fast & stable Tomcat hosting.

Java Hosting with Tomcat
Not Now