Create Spring MVC Project
On the Eclipse, create a Spring MVC project in Spring Boot
Enter Project Information:
- Name: LearnSpringMVCWithRealApps
- Group: com.demo
- Artifact: LearnSpringMVCWithRealApps
- Description: Learn Spring MVC with Real Apps
- Package: com.demo
Select the technologies and libraries to be used:
- Web
- JPA
- MySQL
Click Next button to show Site Information for project
Click Finish button to finish create Spring MVC project
Configure pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>com.demo</groupId>
<artifactId>LearnSpringMVCWithRealApps</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>LearnSpringMVCWithRealApps</name>
<description>Learn Spring MVC with Real Apps</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JSTL tag lib -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- Tomcat for JSP rendering -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL JDBC -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Create Database
Create a database with the name is learn_spring_mvc_with_real_apps. This database have 1 table: Product table
--
-- Table structure for table `product`
--
CREATE TABLE `product` (
`id` int(11) NOT NULL,
`name` varchar(250) NOT NULL,
`price` decimal(10,1) NOT NULL,
`quantity` int(11) NOT NULL,
`description` text NOT NULL,
`status` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Dumping data for table `product`
--
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Mobile 1', '1.0', 5, 'description 2', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Mobile 2', '2.0', 2, 'description 1', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Mobile 3', '11.0', 9, 'description 3', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Laptop 4', '2.0', 15, 'description 9', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Computer 1', '16.0', 8, 'description 7', 0);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Laptop 1', '22.0', 8, 'description 7', 0);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Laptop 2', '4.0', 11, 'description 8', 0);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Laptop 3', '9.0', 15, 'description 9', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `status`) VALUES('Computer 2', '3.0', 8, 'description 7', 0);
Structure of Product Table
Data of Product Table
Configure application.properties
spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
spring.mvc.static-path-pattern=/resources/**
spring.datasource.url= jdbc:mysql://localhost:3306/learn_spring_mvc_with_real_apps
spring.datasource.username=root
spring.datasource.password=123456
server.port=9596
Create Tag File
Create new folder named tags in src\main\webapp\WEB-INF folder. In this folder, create paging.tag file as below:
<%@ tag language="java" pageEncoding="ISO-8859-1"%>
<%@ tag import="org.springframework.util.StringUtils"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ attribute name="pagedListHolder" required="true"
type="org.springframework.beans.support.PagedListHolder"%>
<%@ attribute name="pagedLink" required="true" type="java.lang.String"%>
<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>
<c:if test="${pagedListHolder.pageCount > 1}">
<ul class="pagination">
<c:if test="${!pagedListHolder.firstPage}">
<li class="previous"><a
href="<%=StringUtils.replace(pagedLink, "~", String.valueOf(pagedListHolder.getPage() - 1))%>"><</a></li>
</c:if>
<c:if test="${pagedListHolder.firstLinkedPage > 0}">
<li><a href="<%=StringUtils.replace(pagedLink, "~", "0")%>">1</a></li>
</c:if>
<c:if test="${pagedListHolder.firstLinkedPage > 1}">
<li><span class="pagingDots">...</span>
<li>
</c:if>
<c:forEach begin="${pagedListHolder.firstLinkedPage}"
end="${pagedListHolder.lastLinkedPage}" var="i">
<c:choose>
<c:when test="${pagedListHolder.page == i}">
<li class="active"><a href="#">${i+1}</a></li>
</c:when>
<c:otherwise>
<li><a
href="<%=StringUtils.replace(pagedLink, "~", String.valueOf(jspContext.getAttribute("i")))%>">${i+1}</a>
</li>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if
test="${pagedListHolder.lastLinkedPage < pagedListHolder.pageCount - 2}">
<li><span class="pagingDots">...</span></li>
</c:if>
<c:if
test="${pagedListHolder.lastLinkedPage < pagedListHolder.pageCount - 1}">
<li><a
href="<%=StringUtils.replace(pagedLink, "~", String.valueOf(pagedListHolder.getPageCount() - 1))%>">${pagedListHolder.pageCount}</a></li>
</c:if>
<c:if test="${!pagedListHolder.lastPage}">
<li class="next"><a
href="<%=StringUtils.replace(pagedLink, "~", String.valueOf(pagedListHolder.getPage() + 1))%>">></a></li>
</c:if>
</ul>
</c:if>
Entities Class
Create new package, named com.demo.entities. In this package, create entities class as below:
Product Entity
Create new java class, named Product.java
package com.demo.entities;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column
private String name;
@Column
private BigDecimal price;
@Column
private int quantity;
@Column
private String description;
@Column
private boolean status;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
Create ProductRepository Interface
Create new package named com.demo.repositories. In this package create the ProductRepository interface implements from CrudRepository interface of Spring Data JPA that provides CRUD Operations for an entity.
package com.demo.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.demo.entities.Product;
@Repository("productRepository")
public interface ProductRepository extends CrudRepository<Product, Integer> {
}
Create ProductService Interface
Create new package named com.demo.services. In this package create the ProductService interface as below:
package com.demo.services;
import demo.entities.Product;
public interface ProductService {
public Iterable<Product> findAll();
}
Create ProductServiceImpl class
In com.demo.services package, create ProductServiceImpl class implements method from ProductService interfaces
package com.demo.repositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.demo.entities.Product;
import com.demo.services.ProductService;
@Transactional
@Service("productService")
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository productRepository;
@Override
public Iterable<Product> findAll() {
return productRepository.findAll();
}
}
Create Controllers
Create new package named com.demo.controllers. In this package, create controller as below:
ProductController
Create new java class, named ProductController.java
package com.demo.controllers;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.support.PagedListHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.demo.entities.Product;
import com.demo.services.ProductService;
@Controller
@RequestMapping("product")
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping(method = RequestMethod.GET)
public String index(HttpServletRequest request, ModelMap modelMap) {
List<Product> products = (List<Product>) productService.findAll();
PagedListHolder pagedListHolder = new PagedListHolder(products);
int page = ServletRequestUtils.getIntParameter(request, "p", 0);
pagedListHolder.setPage(page);
pagedListHolder.setPageSize(3);
modelMap.put("pagedListHolder", pagedListHolder);
return "product/index";
}
}
Create Views
Create new folders with path webapp\WEB-INF\views in src\main. In views folder, create JSP Pages as below:
Index View
Create new folder named product. Create new jsp file named index.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="tg" tagdir="/WEB-INF/tags"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Pagination with Spring Data JPA in Spring MVC</title>
</head>
<body>
<div class="container" style="margin-top: 20px;">
<jsp:useBean id="pagedListHolder" scope="request"
type="org.springframework.beans.support.PagedListHolder" />
<c:url value="/product" var="pagedLink">
<c:param name="p" value="~" />
</c:url>
<tg:paging pagedListHolder="${pagedListHolder}"
pagedLink="${pagedLink}" />
<table class="table table-bordered">
<tr>
<th width="20px">Id</th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Status</th>
</tr>
<c:forEach items="${pagedListHolder.pageList}" var="item">
<tr>
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.price}</td>
<td>${item.quantity}</td>
<td>${item.status }</td>
</tr>
</c:forEach>
</table>
<tg:paging pagedListHolder="${pagedListHolder}"
pagedLink="${pagedLink}" />
</div>
</body>
</html>
Structure of Spring MVC Project
Run Application
Select LearnSpringMVCWithRealAppsApplication.java file in com.demo package, right click and select Run As/Spring Boot App menu
Access index method in product controller with following url: http://localhost:9596/product
Output for Page 1
Output for Page 2
Output for Page 3
References
I recommend you refer to the books below to learn more about the knowledge in this article:
- Spring MVC Beginners Guide – Second Edition
- Spring MVC Cookbook
- Spring MVC Blueprints
- Mastering Spring MVC 4
- Spring Boot in Action
- Pro Spring Boot
- Spring Data