Spring MVC Tutorial
Core Spring MVC
Spring MVC - Annotation
Spring MVC - Form Handling
Spring MVC with JSTL
Spring MVC with REST API
Spring MVC with Database
Pagination is a technique to display a large number of records in manageable sets or pages. In web applications, pagination helps in enhancing the user experience by presenting data in a structured manner. When combined with Spring MVC, pagination can be achieved in a seamless and efficient way.
Let's walk through the process of implementing pagination in a Spring MVC application using Spring's Page
and Pageable
interfaces from Spring Data JPA.
Ensure you have the required dependencies in your pom.xml
:
<!-- Spring Web MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.x.x.RELEASE</version> </dependency> <!-- Spring Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- Your database driver here, e.g., H2 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency>
Your repository should extend PagingAndSortingRepository
or JpaRepository
:
public interface UserRepository extends JpaRepository<User, Long> { }
In your controller, use the Pageable
parameter to receive pagination information:
@Controller @RequestMapping("/users") public class UserController { @Autowired private UserRepository userRepository; @GetMapping public String listUsers(@RequestParam(defaultValue = "0") int page, Model model) { Page<User> userPage = userRepository.findAll(PageRequest.of(page, 10)); // 10 records per page model.addAttribute("data", userPage); return "userList"; } }
Display the paginated data and pagination controls:
<table> <thead> <tr> <th>ID</th> <th>Name</th> <!-- Other columns --> </tr> </thead> <tbody> <c:forEach items="${data.content}" var="user"> <tr> <td>${user.id}</td> <td>${user.name}</td> <!-- Other columns --> </tr> </c:forEach> </tbody> </table> <!-- Pagination controls --> <div> <c:if test="${data.totalPages > 0}"> <ul> <c:forEach begin="0" end="${data.totalPages-1}" var="pageNum"> <li><a href="<c:url value='/users?page=${pageNum}' />">${pageNum + 1}</a></li> </c:forEach> </ul> </c:if> </div>
You might want to add some CSS for better presentation of the paginated data and the pagination controls.
The Page
object contains metadata about the total number of pages, the total number of elements, the current page number, etc. This is useful for building pagination controls in the view.
The Pageable
object can be used to specify not just pagination information, but also sorting details.
You can customize the default parameters for Pageable
(like page
, size
, and sort
) by customizing the PageableHandlerMethodArgumentResolver
bean in your configuration.
With this setup, as users navigate between pages, only the data for the current page will be fetched from the database, ensuring efficient resource utilization.
Spring MVC Pagination Example:
Description: This is a basic example showcasing how to implement pagination in a Spring MVC application.
Code Snippet: (Controller)
@Controller public class ProductController { @Autowired private ProductService productService; @RequestMapping("/products") public String getProducts(Model model, @RequestParam(defaultValue = "0") int page) { Page<Product> productPage = productService.getPaginatedProducts(page, 10); model.addAttribute("productPage", productPage); return "productList"; } }
(Service)
@Service public class ProductService { @Autowired private ProductRepository productRepository; public Page<Product> getPaginatedProducts(int page, int size) { Pageable pageable = PageRequest.of(page, size); return productRepository.findAll(pageable); } }
(Thymeleaf - productList.html)
<table> <!-- Display product list --> <tr th:each="product : ${productPage.content}"> <td th:text="${product.name}"></td> <td th:text="${product.price}"></td> </tr> </table> <!-- Display pagination links --> <div th:fragment="pagination"> <ul class="pagination"> <li th:if="${productPage.hasPrevious()}"> <a th:href="@{/products(page=${productPage.previousPageable().pageNumber})}">« Previous</a> </li> <li th:each="i : ${#numbers.sequence(0, productPage.totalPages - 1)}" th:class="${productPage.number == i} ? 'active'"> <a th:href="@{/products(page=${i})}" th:text="${i + 1}"></a> </li> <li th:if="${productPage.hasNext()}"> <a th:href="@{/products(page=${productPage.nextPageable().pageNumber})}">Next »</a> </li> </ul> </div>
Client-Side Pagination with Spring MVC:
Description: This example showcases client-side pagination in a Spring MVC application.
Code Snippet: (Controller and Service are similar to the first example)
(Thymeleaf - productList.html)
<table id="productTable"> <!-- Display product list --> <tr th:each="product : ${productPage.content}"> <td th:text="${product.name}"></td> <td th:text="${product.price}"></td> </tr> </table> <!-- Include the DataTables JavaScript library --> <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script> <!-- Initialize DataTables with pagination --> <script> $(document).ready(function () { $('#productTable').DataTable(); }); </script>
Paginating Data with Spring Data JPA in Spring MVC:
Description: This example demonstrates paginating data using Spring Data JPA in a Spring MVC application.
Code Snippet: (Service)
@Service public class ProductService { @Autowired private ProductRepository productRepository; public Page<Product> getPaginatedProducts(int page, int size) { Pageable pageable = PageRequest.of(page, size); return productRepository.findAll(pageable); } }