diff --git a/persistence-modules/spring-data-jpa-query-3/pom.xml b/persistence-modules/spring-data-jpa-query-3/pom.xml
index 18df57fe14..1dff3024f6 100644
--- a/persistence-modules/spring-data-jpa-query-3/pom.xml
+++ b/persistence-modules/spring-data-jpa-query-3/pom.xml
@@ -30,6 +30,11 @@
javafaker
${javafaker.version}
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
org.springframework.boot
spring-boot-starter-test
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java
new file mode 100644
index 0000000000..7ef4db808b
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/Customer.java
@@ -0,0 +1,14 @@
+package com.baeldung.spring.data.jpa.paging;
+
+public class Customer {
+
+ private String name;
+
+ public Customer(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java
new file mode 100644
index 0000000000..ea418e7c55
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.spring.data.jpa.paging;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CustomerRepository extends JpaRepository {
+
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java
new file mode 100644
index 0000000000..4a3a38991c
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerRestController.java
@@ -0,0 +1,31 @@
+package com.baeldung.spring.data.jpa.paging;
+
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class CustomerRestController {
+
+ private final CustomerService customerService;
+
+ public CustomerRestController(CustomerService customerService) {
+ this.customerService = customerService;
+ }
+
+ @GetMapping("/api/customers")
+ public ResponseEntity> getCustomers(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
+
+ Page customerPage = customerService.getCustomers(page, size);
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-Page-Number", String.valueOf(customerPage.getNumber()));
+ headers.add("X-Page-Size", String.valueOf(customerPage.getSize()));
+
+ return ResponseEntity.ok()
+ .headers(headers)
+ .body(customerPage);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java
new file mode 100644
index 0000000000..73affeb1a1
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/CustomerService.java
@@ -0,0 +1,35 @@
+package com.baeldung.spring.data.jpa.paging;
+
+import java.util.List;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CustomerService {
+
+ public CustomerService(CustomerRepository customerRepository) {
+ this.customerRepository = customerRepository;
+ }
+
+ private final CustomerRepository customerRepository;
+
+ public Page getCustomers(int page, int size) {
+
+ Pageable pageRequest = createPageRequestUsing(page, size);
+
+ List allCustomers = customerRepository.findAll();
+ int start = (int) pageRequest.getOffset();
+ int end = Math.min((start + pageRequest.getPageSize()), allCustomers.size());
+
+ List pageContent = allCustomers.subList(start, end);
+ return new PageImpl<>(pageContent, pageRequest, allCustomers.size());
+ }
+
+ private Pageable createPageRequestUsing(int page, int size) {
+ return PageRequest.of(page, size);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java
new file mode 100644
index 0000000000..58a6b43ff3
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/paging/PagingApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.spring.data.jpa.paging;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PagingApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PagingApplication.class, args);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerIntegrationTest.java b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerIntegrationTest.java
new file mode 100644
index 0000000000..c928ab2a5d
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerControllerIntegrationTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.spring.data.jpa.paging;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.IntStream;
+
+import org.json.JSONObject;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+@WebMvcTest(CustomerRestController.class)
+public class CustomerControllerIntegrationTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @MockBean
+ private CustomerService customerService;
+
+ @BeforeEach
+ void setup() {
+ List allCustomers = getAllCustomers();
+ Page customerPage = new PageImpl<>(allCustomers, PageRequest.of(1, 5), allCustomers.size());
+
+ when(customerService.getCustomers(1, 5)).thenReturn(customerPage);
+
+ }
+
+ private static List getAllCustomers() {
+ List customers = new ArrayList<>();
+ IntStream.range(0, 20)
+ .forEach(i -> {
+ Customer customer = new Customer((Integer.toString(i)));
+ customers.add(customer);
+ });
+ return customers;
+ }
+
+ @Test
+ void givenTotalCustomers20_whenGetRequestWithPageAndSize_thenPagedReponseIsReturnedFromDesiredPageAndSize() throws Exception {
+
+ MvcResult result = mockMvc.perform(get("/api/customers?page=1&size=5"))
+ .andExpect(status().isOk())
+ .andReturn();
+
+ MockHttpServletResponse response = result.getResponse();
+
+ JSONObject jsonObject = new JSONObject(response.getContentAsString());
+ assertThat(jsonObject.get("totalPages")).isEqualTo(4);
+ assertThat(jsonObject.get("totalElements")).isEqualTo(20);
+ assertThat(jsonObject.get("number")).isEqualTo(1);
+ assertThat(jsonObject.get("size")).isEqualTo(5);
+ assertThat(jsonObject.get("content")).isNotNull();
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceUnitTest.java b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceUnitTest.java
new file mode 100644
index 0000000000..1a34822527
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/paging/CustomerServiceUnitTest.java
@@ -0,0 +1,80 @@
+package com.baeldung.spring.data.jpa.paging;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.data.domain.Page;
+
+@ExtendWith(MockitoExtension.class)
+public class CustomerServiceUnitTest {
+
+ @Mock
+ private CustomerRepository customerRepository;
+
+ @InjectMocks
+ private CustomerService customerService;
+
+ private static final List ALL_CUSTOMERS = Arrays.asList(
+ new Customer("Ali"), new Customer("Brian"),
+ new Customer("Coddy"), new Customer("Di"),
+ new Customer("Eve"), new Customer("Fin"),
+ new Customer("Grace"), new Customer("Harry"),
+ new Customer("Ivan"), new Customer("Judy"),
+ new Customer("Kasim"), new Customer("Liam"),
+ new Customer("Mike"), new Customer("Nick"),
+ new Customer("Omar"), new Customer("Penny"),
+ new Customer("Queen"), new Customer("Rob"),
+ new Customer("Sue"), new Customer("Tammy"));
+
+ private static final List PAGE_1_CONTENTS = Arrays.asList("Ali", "Brian", "Coddy", "Di", "Eve");
+
+ private static final List PAGE_2_CONTENTS = Arrays.asList("Fin", "Grace", "Harry", "Ivan", "Judy");
+
+ private static final List PAGE_3_CONTENTS = Arrays.asList("Kasim", "Liam", "Mike", "Nick", "Omar");
+
+ private static final List PAGE_4_CONTENTS = Arrays.asList("Penny", "Queen", "Rob", "Sue", "Tammy");
+
+ private static final List EMPTY_PAGE = Arrays.asList();
+
+ @BeforeEach
+ void setup() {
+ when(customerRepository.findAll()).thenReturn(ALL_CUSTOMERS);
+ }
+
+ private static Collection