Merge pull request #536 from jesus-dayo/master
[spring-rest-angular-pagination]initial draft
This commit is contained in:
commit
603955f3f8
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>angular-spring-rest-sample</artifactId>
|
||||
<name>angular-spring-rest-sample</name>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0</version>
|
||||
<packaging>war</packaging>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.3.3.RELEASE</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<spring.data.version>1.12.2.RELEASE</spring.data.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>spring-mock-mvc</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>angular-spring-rest-sample</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -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<Student> 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<Student> getMockDataStudents(){
|
||||
return studentList;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Student> findPaginated(@RequestParam("page") int page, @RequestParam("size") int size){
|
||||
|
||||
Page<Student> resultPage = service.findPaginated(page, size);
|
||||
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.baeldung.web.service;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface IOperations<T> {
|
||||
|
||||
Page<T> findPaginated(int page, int size);
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package org.baeldung.web.service;
|
||||
|
||||
import org.baeldung.web.vo.Student;
|
||||
|
||||
public interface StudentService extends IOperations<Student>{
|
||||
|
||||
}
|
|
@ -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<Student> mockDataStudent = MockStudentData.getMockDataStudents();
|
||||
|
||||
@Override
|
||||
public Page<Student> findPaginated(int page, int size){
|
||||
Page<Student> studentPage = getPage(page, size);
|
||||
return studentPage;
|
||||
}
|
||||
|
||||
private Page<Student> 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<Student>(mockDataStudent.subList(from, to),
|
||||
new PageRequest(page,size),
|
||||
mockDataStudent.size());
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
server.contextPath=/StudentDirectory
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
</web-app>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="app">
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
|
||||
<script src="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.js"></script>
|
||||
<script src="view/app.js"></script>
|
||||
</head>
|
||||
<body >
|
||||
<div ng-controller="StudentCtrl as vm">
|
||||
<div ui-grid="gridOptions" class="grid" ui-grid-pagination></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
};
|
||||
|
||||
}]);
|
|
@ -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() );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue