REST Pagination in Spring

This commit is contained in:
Umesh Awasthi
2018-06-17 14:01:55 -07:00
parent ba5f0b41a5
commit 18241f5c17
13 changed files with 414 additions and 0 deletions

25
spring/rest-pagination/.gitignore vendored Normal file
View File

@@ -0,0 +1,25 @@
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

View File

@@ -0,0 +1,72 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javadevjournal</groupId>
<artifactId>rest-pagination</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>REST Pagnination With Spring</name>
<description>Project demonstrating how to build pagination in Spring powered REST API</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</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-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</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>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</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>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,15 @@
package com.javadevjournal.rest;
import com.javadevjournal.rest.jpa.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RestPagninationWithSpringApplication {
public static void main(String[] args) {
SpringApplication.run(RestPagninationWithSpringApplication.class, args);
}
}

View File

@@ -0,0 +1,20 @@
package com.javadevjournal.rest.assembler;
import com.javadevjournal.rest.controller.ProductRESTController;
import com.javadevjournal.rest.data.ProductData;
import com.javadevjournal.rest.entity.ProductEntity;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.mvc.ResourceAssemblerSupport;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
@Component
public class ProductResourceAssembler{
}

View File

@@ -0,0 +1,49 @@
package com.javadevjournal.rest.controller;
import com.javadevjournal.rest.entity.ProductEntity;
import com.javadevjournal.rest.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
@RestController
public class ProductRESTController {
@Autowired
private ProductService productService;
@Autowired private EntityLinks links;
@GetMapping(value = "/products",produces =MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PagedResources<ProductEntity>> AllProducts(Pageable pageable, PagedResourcesAssembler assembler){
Page<ProductEntity> products = productService.findAllProducts(pageable);
PagedResources<ProductEntity> pr= assembler.toResource(products,linkTo(ProductRESTController.class).slash("/products").withSelfRel());
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Link",createLinkHeader(pr));
return new ResponseEntity<>(assembler.toResource(products,linkTo(ProductRESTController.class).slash("/products").withSelfRel()),responseHeaders,HttpStatus.OK);
}
private String createLinkHeader(PagedResources<ProductEntity> pr){
final StringBuilder linkHeader = new StringBuilder();
linkHeader.append(buildLinkHeader( pr.getLinks("first").get(0).getHref(),"first"));
linkHeader.append(", ");
linkHeader.append(buildLinkHeader( pr.getLinks("next").get(0).getHref(),"next"));
return linkHeader.toString();
}
public static String buildLinkHeader(final String uri, final String rel) {
return "<" + uri + ">; rel=\"" + rel + "\"";
}
}

View File

@@ -0,0 +1,44 @@
package com.javadevjournal.rest.data;
import com.javadevjournal.rest.entity.ProductEntity;
import org.springframework.hateoas.ResourceSupport;
import java.util.List;
public class ProductData extends ResourceSupport {
List<ProductEntity> products;
private int pageNumber;
private int size;
private int totalPages;
private int totalElements;
public ProductData(List<ProductEntity> products, int pageNumber, int size, int totalPages, int totalElements) {
this.products = products;
this.pageNumber = pageNumber;
this.size = size;
this.totalPages = totalPages;
this.totalElements = totalElements;
}
public List<ProductEntity> getProducts() {
return products;
}
public int getPageNumber() {
return pageNumber;
}
public int getSize() {
return size;
}
public int getTotalPages() {
return totalPages;
}
public int getTotalElements() {
return totalElements;
}
}

View File

@@ -0,0 +1,95 @@
package com.javadevjournal.rest.entity;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "product")
public class ProductEntity {
@Id
@GeneratedValue
private Integer id;
@Column
private String code;
@Column
private String name;
@Column
private String description;
@Column
private Double price;
@Column
private Integer stock;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ProductEntity)) return false;
ProductEntity that = (ProductEntity) o;
return Objects.equals(id, that.id) &&
Objects.equals(getCode(), that.getCode()) &&
Objects.equals(getName(), that.getName()) &&
Objects.equals(getDescription(), that.getDescription()) &&
Objects.equals(getPrice(), that.getPrice()) &&
Objects.equals(getStock(), that.getStock());
}
@Override
public int hashCode() {
return Objects.hash(id, getCode(), getName(), getDescription(), getPrice(), getStock());
}
}

View File

@@ -0,0 +1,37 @@
package com.javadevjournal.rest.event;
import com.javadevjournal.rest.entity.ProductEntity;
import com.javadevjournal.rest.jpa.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@Component
public class PostConstructBean {
@Autowired
private ProductRepository productRepository;
@PostConstruct
public void init(){
List<ProductEntity> productEntityList = new ArrayList<>();
for(int i = 0; i<100; i++){
ProductEntity product = new ProductEntity();
product.setCode(String.valueOf(i));
product.setDescription("Description of Product "+i);
product.setName("Name "+i);
product.setPrice(i+10.00);
product.setStock(i+2);
productEntityList.add(product);
}
productRepository.saveAll(productEntityList);
Iterable<ProductEntity> pro= productRepository.findAll();
pro.forEach(System.out::println);
}
}

View File

@@ -0,0 +1,7 @@
package com.javadevjournal.rest.jpa;
import com.javadevjournal.rest.entity.ProductEntity;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface ProductRepository extends PagingAndSortingRepository<ProductEntity,Integer> {
}

View File

@@ -0,0 +1,24 @@
package com.javadevjournal.rest.service;
import com.javadevjournal.rest.entity.ProductEntity;
import com.javadevjournal.rest.jpa.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@Service
public class DefaultProductService implements ProductService {
@Autowired
private ProductRepository productRepository;
@Override
public Page<ProductEntity> findAllProducts(Pageable pageable) {
return productRepository.findAll(pageable);
}
public ProductRepository getProductRepository() {
return productRepository;
}
}

View File

@@ -0,0 +1,10 @@
package com.javadevjournal.rest.service;
import com.javadevjournal.rest.entity.ProductEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
public interface ProductService {
public Page<ProductEntity> findAllProducts(Pageable pageable);
}

View File

@@ -0,0 +1,16 @@
package com.javadevjournal.rest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RestPagninationWithSpringApplicationTests {
@Test
public void contextLoads() {
}
}