diff --git a/spring-rest-angular-pagination/StudentDirectory/pom.xml b/spring-rest-angular-pagination/StudentDirectory/pom.xml
new file mode 100644
index 0000000000..8dab851ef2
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/pom.xml
@@ -0,0 +1,86 @@
+
+
+ 4.0.0
+ angular-spring-rest-sample
+ angular-spring-rest-sample
+ com.baeldung
+ 1.0
+ war
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.3.3.RELEASE
+
+
+ 1.12.2.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+ org.springframework
+ spring-test
+ test
+
+
+ org.apache.commons
+ commons-lang3
+ 3.3
+
+
+ com.google.guava
+ guava
+ 19.0
+
+
+ junit
+ junit
+ test
+
+
+ io.rest-assured
+ rest-assured
+ 3.0.0
+ test
+
+
+ io.rest-assured
+ spring-mock-mvc
+ 3.0.0
+ test
+
+
+
+ angular-spring-rest-sample
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ false
+
+
+
+
+
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java
new file mode 100644
index 0000000000..df70780a87
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java
@@ -0,0 +1,39 @@
+package org.baeldung.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.baeldung.web.vo.Student;
+
+public class MockStudentData {
+
+ private static List studentList = new ArrayList<>();
+
+ static {
+ studentList.add(new Student("1", "Bryan", "Male", 20));
+ studentList.add(new Student("2", "Ben", "Male", 22));
+ studentList.add(new Student("3", "Lisa", "Female", 24));
+ studentList.add(new Student("4", "Sarah", "Female", 26));
+ studentList.add(new Student("5", "Jay", "Male", 20));
+ studentList.add(new Student("6", "John", "Male", 22));
+ studentList.add(new Student("7", "Jordan", "Male", 24));
+ studentList.add(new Student("8", "Rob", "Male", 26));
+ studentList.add(new Student("9", "Will", "Male", 20));
+ studentList.add(new Student("10", "Shawn", "Male", 22));
+ studentList.add(new Student("11", "Taylor", "Female", 24));
+ studentList.add(new Student("12", "Venus", "Female", 26));
+ studentList.add(new Student("13", "Vince", "Male", 20));
+ studentList.add(new Student("14", "Carol", "Female", 22));
+ studentList.add(new Student("15", "Joana", "Female", 24));
+ studentList.add(new Student("16", "Dion", "Male", 26));
+ studentList.add(new Student("17", "Evans", "Male", 20));
+ studentList.add(new Student("18", "Bart", "Male", 22));
+ studentList.add(new Student("19", "Jenny", "Female", 24));
+ studentList.add(new Student("20", "Kristine", "Female", 26));
+ }
+
+ public static List getMockDataStudents(){
+ return studentList;
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java
new file mode 100644
index 0000000000..3105d1cb11
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java
@@ -0,0 +1,27 @@
+package org.baeldung.web.exception;
+
+public class MyResourceNotFoundException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4088649120307193208L;
+
+ public MyResourceNotFoundException() {
+ super();
+ }
+
+ public MyResourceNotFoundException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public MyResourceNotFoundException(final String message) {
+ super(message);
+ }
+
+ public MyResourceNotFoundException(final Throwable cause) {
+ super(cause);
+ }
+
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java
new file mode 100644
index 0000000000..b3b0dad98a
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java
@@ -0,0 +1,26 @@
+package org.baeldung.web.main;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.web.filter.ShallowEtagHeaderFilter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@SpringBootApplication
+@EnableAutoConfiguration
+@ComponentScan("org.baeldung")
+public class Application extends WebMvcConfigurerAdapter {
+
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
+ return new ShallowEtagHeaderFilter();
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java
new file mode 100644
index 0000000000..5ff24ec0f2
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java
@@ -0,0 +1,26 @@
+package org.baeldung.web.rest;
+
+import org.baeldung.web.service.StudentService;
+import org.baeldung.web.vo.Student;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class StudentDirectoryRestController {
+
+ @Autowired
+ private StudentService service;
+
+ @RequestMapping(value = "/student/get", params = { "page", "size" }, method = RequestMethod.GET)
+ public Page findPaginated(@RequestParam("page") int page, @RequestParam("size") int size){
+
+ Page resultPage = service.findPaginated(page, size);
+
+ return resultPage;
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java
new file mode 100644
index 0000000000..0b408106ce
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java
@@ -0,0 +1,9 @@
+package org.baeldung.web.service;
+
+import org.springframework.data.domain.Page;
+
+public interface IOperations {
+
+ Page findPaginated(int page, int size);
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java
new file mode 100644
index 0000000000..5c4487254a
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java
@@ -0,0 +1,7 @@
+package org.baeldung.web.service;
+
+import org.baeldung.web.vo.Student;
+
+public interface StudentService extends IOperations{
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java
new file mode 100644
index 0000000000..3b6dda6fb1
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java
@@ -0,0 +1,36 @@
+package org.baeldung.web.service;
+
+import java.util.List;
+
+import org.baeldung.mock.MockStudentData;
+import org.baeldung.web.exception.MyResourceNotFoundException;
+import org.baeldung.web.vo.Student;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+@Service
+public class StudentServiceImpl implements StudentService {
+
+ private List mockDataStudent = MockStudentData.getMockDataStudents();
+
+ @Override
+ public Page findPaginated(int page, int size){
+ Page studentPage = getPage(page, size);
+ return studentPage;
+ }
+
+ private Page getPage(int page, int size) {
+ page = page != 0?page - 1:page;
+ int from = Math.max(0, page * size);
+ int to = Math.min(mockDataStudent.size(), (page + 1) * size);
+ if(from > to){
+ throw new MyResourceNotFoundException("page number is higher than total pages.");
+ }
+ return new PageImpl(mockDataStudent.subList(from, to),
+ new PageRequest(page,size),
+ mockDataStudent.size());
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java
new file mode 100644
index 0000000000..11c503815d
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java
@@ -0,0 +1,60 @@
+package org.baeldung.web.vo;
+
+import java.io.Serializable;
+
+public class Student implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public Student() {
+ }
+
+ public Student(String studentId, String name, String gender, Integer age) {
+ super();
+ this.studentId = studentId;
+ this.name = name;
+ this.gender = gender;
+ this.age = age;
+ }
+
+ private String studentId;
+ private String name;
+ private String gender;
+ private Integer age;
+
+ public String getStudentId() {
+ return studentId;
+ }
+
+ public void setStudentId(String studentId) {
+ this.studentId = studentId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+}
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties b/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties
new file mode 100644
index 0000000000..a9bf6ca218
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties
@@ -0,0 +1 @@
+server.contextPath=/StudentDirectory
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..ff65bd6b96
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ index.html
+
+
+
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html
new file mode 100644
index 0000000000..56a1273588
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js
new file mode 100644
index 0000000000..522c49c8cb
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js
@@ -0,0 +1,54 @@
+var app = angular.module('app', ['ui.grid','ui.grid.pagination']);
+
+app.controller('StudentCtrl', ['$scope','StudentService', function ($scope,StudentService) {
+ var paginationOptions = {
+ pageNumber: 1,
+ pageSize: 5,
+ sort: null
+ };
+
+ StudentService.getStudents(paginationOptions.pageNumber,
+ paginationOptions.pageSize).success(function(data){
+ $scope.gridOptions.data = data.content;
+ $scope.gridOptions.totalItems = data.totalElements;
+ });
+
+ $scope.gridOptions = {
+ paginationPageSizes: [5, 10, 20],
+ paginationPageSize: paginationOptions.pageSize,
+ enableColumnMenus:false,
+ columnDefs: [
+ { name: 'studentId' },
+ { name: 'name' },
+ { name: 'gender' },
+ { name: 'age' }
+ ],
+ onRegisterApi: function(gridApi) {
+ $scope.gridApi = gridApi;
+ gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ paginationOptions.pageNumber = newPage;
+ paginationOptions.pageSize = pageSize;
+ StudentService.getStudents(newPage,pageSize).success(function(data){
+ $scope.gridOptions.data = data.content;
+ $scope.gridOptions.totalItems = data.totalElements;
+ });
+ });
+ }
+ };
+
+}]);
+
+app.service('StudentService',['$http', function ($http) {
+
+ function getStudents(pageNumber,size) {
+ return $http({
+ method: 'GET',
+ url: 'student/get?page='+pageNumber+'&size='+size
+ });
+ }
+
+ return {
+ getStudents:getStudents
+ };
+
+}]);
\ No newline at end of file
diff --git a/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java b/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java
new file mode 100644
index 0000000000..3e476bf0d0
--- /dev/null
+++ b/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java
@@ -0,0 +1,49 @@
+package org.baeldung.web.service;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.baeldung.web.main.Application;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import io.restassured.RestAssured;
+import io.restassured.response.Response;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+@WebAppConfiguration
+@IntegrationTest("server.port:8080")
+public class StudentServiceTest{
+
+ private String getURL() {
+ return "/StudentDirectory/student/get";
+ }
+
+ @Test
+ public void whenResourcesAreRetrievedPaged_then200IsReceived(){
+ Response response = RestAssured.given().get(getURL()+ "?page=0&size=2").andReturn();
+
+ assertTrue(response.getStatusCode() == 200 );
+ }
+
+ @Test
+ public void whenPageOfResourcesAreRetrievedOutOfBounds_then404IsReceived(){
+ String url = getURL()+ "?page=" + RandomStringUtils.randomNumeric(5) + "&size=2";
+ Response response = RestAssured.given().get(url);
+
+ assertTrue(response.getStatusCode() == 500 );
+ }
+
+ @Test
+ public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources(){
+ Response response = RestAssured.given().get(getURL() + "?page=1&size=2" );
+ assertFalse(response.getBody().jsonPath().getList("content").isEmpty() );
+ }
+
+}