Spring MVC – Building Pagination and Sorting in Web Applications
Last Updated :
25 Nov, 2024
In modern web applications, the data can often be too large to be displayed in a single format. The use of pagination and sorting is essential to enhance the user experience and handle large datasets efficiently. Pagination breaks down into manageable chunks or pages, while sorting allows users to view data sequentially.
In this article, we will learn the process of the implementing pagination and sorting in the Spring MVC application.
Prerequisites:
- Basic knowledge of the Java and Spring Framework.
- Basic understanding of the MVC architecture.
- Maven for building dependency management.
- JDK and IntelliJ IDEA should have installed in the system.
Pagination
Paging is the process of dividing large data into smaller chunks or pages. In Spring MVC applications, the Pageable interface can be used, which allows dynamic data retrieval based on the requested page number and size
Sorting
Sorting enables the users to order the data on the specific fields, such as names, dates, or any other attributes. The Sort class in the Spring Data JPA provides various options for sorting data.
Implement Pagination and Sorting in a Spring MVC Application
This example project demonstrate the pagination and sorting in the Spring MVC application. This project will allow the user to navigate through the list of the products sorted by specified field (such as name or price), and display the data in pages.
Step 1: Create a new Spring Boot Project
Create a new Spring Boot Project using the IntelliJ IDEA. Choose the following options:
- Name: spring-pagination-sorting-example
- Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.
Step 2: Add the Dependencies
Add the following dependencies into the Spring Boot Project:
- Spring Web
- Spring DevTools
- Spring Data JPA
- MySQL Driver
- Lombok
- Thymeleaf
Click on the Create button.
Step 3: Configure Application Properties
Open the application.properties file and add the following MySQL and Hibernate configurations.
spring.application.name=spring-pagination-sorting-example
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=mypassword
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
Step 4: Create the Product Class
Create the Product entity. This class will represent the data to be paginated and sorted.
Product.java:
Java
package com.gfg.springpaginationsortingexample;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
}
Step 5: Create the ProductRepository Interface
Create the ProductRepository interface. This interface extends the JpaRepository interface and enables the pagination and sorting of the Product entities.
ProductRepository.java:
Java
package com.gfg.springpaginationsortingexample;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductRepository extends JpaRepository<Product, Long> {
}
Step 6: Create the ProductService Class
Create the ProductService class. This service class will handle the business logic for retrieving pagination and sorted data from the database.
ProductService.java:
Java
package com.gfg.springpaginationsortingexample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public Page<Product> findPaginatedAndSorted(int pageNo, int pageSize, String sortField, String sortDirection) {
Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) ?
Sort.by(sortField).ascending() :
Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
return productRepository.findAll(pageable);
}
}
Step 7: Create the ProductController Class
Create the ProductController class. This controller handles the requests for the pagination and sorting and forward the data to the view layer.
ProductController.java:
Java
package com.gfg.springpaginationsortingexample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class ProductController {
@Autowired
private ProductService productService;
/**
* Method to display the products page with pagination and sorting.
* @param pageNo The current page number.
* @param sortField The field to sort the products by.
* @param sortDir The direction of the sort (ascending or descending).
* @param model The model to pass attributes to the view.
* @return The name of the view to render.
*/
@GetMapping("/products")
public String viewProductsPage(
@RequestParam(value = "pageNo", defaultValue = "1") int pageNo,
@RequestParam(value = "sortField", defaultValue = "name") String sortField,
@RequestParam(value = "sortDir", defaultValue = "asc") String sortDir,
Model model) {
int pageSize = 10;
Page<Product> page = productService.findPaginatedAndSorted(pageNo, pageSize, sortField, sortDir);
List<Product> productList = page.getContent();
model.addAttribute("currentPage", pageNo);
model.addAttribute("totalPages", page.getTotalPages());
model.addAttribute("totalItems", page.getTotalElements());
model.addAttribute("sortField", sortField);
model.addAttribute("sortDir", sortDir);
model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
model.addAttribute("products", productList);
return "products";
}
}
Step 8: Main Class
No changes are required in the main class.
Java
package com.gfg.springpaginationsortingexample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringPaginationSortingExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringPaginationSortingExampleApplication.class, args);
}
}
Step 9: View Layer
This thymeleaf template will render the paginated and sorted product list along with the pagination controls and sorting options.
products.html:
HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Paginated and Sorted Products</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f9f9f9;
}
h2 {
color: #4CAF50;
}
table {
width: 100%;
border-collapse: collapse;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 12px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
a.sort-link {
text-decoration: none;
color: #4CAF50;
}
a.sort-link:hover {
text-decoration: underline;
}
ul {
list-style-type: none;
padding: 0;
}
ul li {
display: inline;
margin-right: 10px;
}
ul li a {
text-decoration: none;
color: #4CAF50;
}
ul li a:hover {
text-decoration: underline;
}
.pagination {
margin-top: 20px;
}
</style>
</head>
<body>
<h2>Products</h2>
<table>
<thead>
<tr>
<th>
<!-- Toggle sorting for Product Name -->
<a th:href="@{/products(pageNo=${currentPage}, sortField='name', sortDir=${reverseSortDir})}"
class="sort-link">
Product Name
<!-- Display ▲ if ascending, ▼ if descending -->
<span th:text="${sortField == 'name' ? (sortDir == 'asc' ? '▲' : '▼') : ''}"></span>
</a>
</th>
<th>
<!-- Toggle sorting for Price -->
<a th:href="@{/products(pageNo=${currentPage}, sortField='price', sortDir=${reverseSortDir})}"
class="sort-link">
Price
<!-- Display ▲ if ascending, ▼ if descending -->
<span th:text="${sortField == 'price' ? (sortDir == 'asc' ? '▲' : '▼') : ''}"></span>
</a>
</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${products}">
<td th:text="${product.name}">Product Name</td>
<td th:text="${product.price}">Price</td>
</tr>
</tbody>
</table>
<!-- Pagination -->
<div class="pagination">
<ul>
<li th:if="${currentPage > 1}">
<a th:href="@{/products(pageNo=${currentPage - 1}, sortField=${sortField}, sortDir=${sortDir})}">Previous</a>
</li>
<li th:if="${currentPage < totalPages}">
<a th:href="@{/products(pageNo=${currentPage + 1}, sortField=${sortField}, sortDir=${sortDir})}">Next</a>
</li>
</ul>
</div>
</body>
</html>
pom.xml file:
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>spring-pagination-sorting-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-pagination-sorting-example</name>
<description>spring-pagination-sorting-example</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 10: Run the Application
Once the project is completed, run the project, and it will start at port 8080.
Application Logs:
Step 11: Testing the Application
Now, type the below URL in any browser, and it will display the below output.
http://localhost:8080/products
Output Video:
This setup provides a complete example of how to implement the pagination and sorting in the Spring MVC application with Thymeleaf.
Similar Reads
Pagination and Sorting with Spring Data JPA Pagination and sorting are crucial features when dealing with large datasets in applications. They can help to break down into manageable chunks and provide a way to order the data according to specific criteria. In the Spring Boot application using Spring Data JPA, we can easily implement these fea
5 min read
Pet Clinic Application using Spring Boot Every Pet clinic need Pet Clinic application becaue it plays an important role in the real world in saving pets from different situations. Mostly, online Pet Clinic applications are developed with the required business logic. Here, we've created a simple Spring Boot Application for the Pet Clinic Ap
14 min read
Spring MVC - Pagination with Example We will be explaining how we can implement pagination in Spring MVC Application. This is required when we need to show a lot of data on pages. Suppose in an e-commerce site we have a lot of products but we can't show all of those on a single page, so we will show only 20 products on each page. This
3 min read
Difference Between Spring MVC and Spring WebFlux Spring MVCSpring MVC Framework takes on the Model-View-Controller design pattern, which moves around the Dispatcher Servlet, also called the Front Controller. With the help of annotations like @Controller and @RequestMapping, the by-default handler becomes a robust(strong) tool with a diverse set of
5 min read
Spring MVC Interview Questions and Answers Spring MVC is a powerful Java framework for building web applications. It is known for its complete configuration options, seamless integration with other Java frameworks, and robust architecture. Many top companies, including Netflix, Amazon, Google, and Airbnb, rely on Spring MVC to build scalable
15 min read