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
How to implement pagination in React Redux Applications?
Pagination is a common requirement in web applications. It is very helpful when we wish to display or manage a large dataset on the website in an aesthetic manner. Whenever it comes to displaying a large number of data, state handling comes into the picture. The idea of pagination has a good binding
5 min read
How to Implement Filtering, Sorting, and Pagination in Flask
Python-based Flask is a microweb framework. Due to the fact that it doesn't require any specific tools or libraries, it is categorized as a micro-framework. It lacks any components where pre-existing third-party libraries already provide common functionality, such as a database abstraction layer, fo
6 min read
How to Build a RESTful API with Spring Boot and Spring MVC?
RESTful APIs have become the standard for building scalable and maintainable web services in web development. REST (Representational State Transfer) enables a stateless, client-server architecture where resources are accessed via standard HTTP methods. This article demonstrates how to create a RESTf
7 min read
How to Create Pagination in Node.js using Skip and Limit ?
Creating pagination in Node.js using the skip and limit methods. This approach efficiently retrieves specific data subsets from a database, improving performance and user experience by loading content in manageable segments rather than all at once. What is Pagination?Pagination is a very helpful met
4 min read
What is Sorting in DSA | Sorting meaning
Sorting is defined as the process of arranging a collection of data elements in a specific order, usually in ascending or descending order based on a specific attribute of the data elements. Characteristics of Sorting:Time Complexity: Time complexity, a measure of how long it takes to run an algorit
3 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
Software Testing - Web Application Testing Checklist with Test Scenarios
Web testing or web application testing ensures that your website functions as you or your clients expect as per requirements gathered during the project's initial stages. It is a comprehensive scope that touches multiple disciplines, including usability, functionality, compatibility, security, perfo
15+ min read