Module 7: Product Service RESTful Web Service: Pagination and Filtering - dineshmadhup/RESTful-Web-Service GitHub Wiki

Note:

In this Module there ischange in code in STEP-3 (ProductService.java) and STEP-4 (ProductResource.java) compare to Module-6. Also one new File is added called ProductFilterBean.java
The aim of Pagination and Filtering is to allow the user to find and filter the products of user choice.

For example:

http://localhost:8080/productService/webapi/products?start=1&size=1 http://localhost:8080/productService/webapi/products?year=2016

In this demonstration we show you three operation which is: Create, Read and Update

Step: 1

First of all we have created Product model which has some features which is:

Product id => pid
Product name =>productName
Product Price =>productPrice
Date Created => created

In Java we have defined the Product features with the help of Constructors and and some methods - setters and getters as shown below:

Package: org.dinesh.softarica.productService.model

Product.java

@XmlRootElement
public class Product {

private long pid;
private String productName;
private Date created;
private String productPrice;

public Product() {
	
}

public Product(long pid, String productName, String productPrice) {
	this.pid = pid;
	this.productName = productName;
	this.productPrice = productPrice;
	this.created = new Date();
}

public long getPid() {
	return pid;
}

public void setPid(long pid) {
	this.pid = pid;
}

public String getProductName() {
	return productName;
}

public void setProductName(String productName) {
	this.productName = productName;
}

public Date getCreated() {
	return created;
}

public void setCreated(Date created) {
	this.created = created;
}

public String getProductPrice() {
	return productPrice;
}

public void setProductPrice(String productPrice) {
	this.productPrice = productPrice;
}

}

}

Here you notice the annotation we have used @XmlRootElement

The @XmlRootElement annotation can be used with the following program elements:
• a top level class
• an enum type

When a top level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document.

Step: 2

Now the Product is needed to be stored in databases. Rather than creating database using MySQL or SQL we have used Map to store the products.

Package: org.dinesh.softarica.productService.database

DatabaseClass.java

public class DatabaseClass {

private static Map<Long, Product> myProducts = new HashMap<>();

public static Map<Long, Product>getProduct() {
	return myProducts;
}

}

Step: 3

Now we create a service where we define some methods so that we can store product details in DatabaseClass.

package: org.dinesh.softarica.productService.service;

ProductService.java

public class ProductService {

// Creating MAP with Key Long and value Product
private Map<Long, Product> myProducts = DatabaseClass.getProduct();

// No-arg constructor
public ProductService() {

	myProducts.put(1L, new Product(1, "IPhone7", "900"));
}

public List<Product> getAllProducts() {
	return new ArrayList<Product>(myProducts.values());
}

 public Product getProduct(long id) {
 return myProducts.get(id);
 }
 
 //Filtering based on year
 public List<Product> getAllProductsForYear(int year) {
	 List<Product> productsForYear = new ArrayList<>();
	 Calendar cal = Calendar.getInstance();
	 for(Product product: myProducts.values()) {
		 cal.setTime(product.getCreated());
		 if(cal.get(Calendar.YEAR) == year) {
			 productsForYear.add(product); 
		 }
	 }
	 return productsForYear;
 }
 
 // Pagination
 public List<Product> getAllProductsPaginated(int start, int size) {
	 ArrayList<Product> list = new ArrayList<Product>(myProducts.values());
	 if(start + size > list.size())
		 return new ArrayList<Product>();
	 return list.subList(start, start + size);
 }


// Create operation
public Product addProduct(Product product) {
	product.setPid(myProducts.size() + 1);
	myProducts.put(product.getPid(), product);
	return product;
}

// Update Product
public Product updateProduct(Product product) {
	if(product.getPid() <= 0) {
		return null;
	}
	myProducts.put(product.getPid(), product);
	return product;
}


// Delete Operation
public Product removeProduct(long pid) {
	return myProducts.remove(pid);
}

}

Step: 4

Creating resources

package: org.dinesh.softarica.productService.resources;

ProductResource.java

@Path("/products")
/* Adding Produces and Consumes annotation on class level /
/
do not require at each individual method */
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class ProductResource {

ProductService productService = new ProductService();

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Product> getJsonProduct(@BeanParam ProductFilterBean filterBean) {
	System.out.println("Json method is called");
	if(filterBean.getYear() > 0) {
		return productService.getAllProductsForYear(filterBean.getYear());
	}
	if(filterBean.getStart() >=0 && filterBean.getSize() > 0) {
		return productService.getAllProductsPaginated(filterBean.getStart(), filterBean.getSize());
	}
	return productService.getAllProducts();
}

@GET
@Produces(MediaType.TEXT_XML)
public List<Product> getXmlProduct(@BeanParam ProductFilterBean filterBean) {
	System.out.println("Json method is called");
	if(filterBean.getYear() > 0) {
		return productService.getAllProductsForYear(filterBean.getYear());
	}
	if(filterBean.getStart() >=0 && filterBean.getSize() > 0) {
		return productService.getAllProductsPaginated(filterBean.getStart(), filterBean.getSize());
	}
	return productService.getAllProducts();
}

@GET
@Path("/{productId}")
public Product getproduct(@PathParam("productId") long pid) {
	return productService.getProduct(pid);
	
}

@POST
//@Consumes(MediaType.APPLICATION_JSON)
//@Produces(MediaType.APPLICATION_JSON)
public Product addProduct(Product product) {
	return productService.addProduct(product);
}

@PUT
@Path("/{productId}")
public Product updateProduct(@PathParam("productId") long pid, Product product) {
	product.setPid(pid);
	return productService.updateProduct(product);
}

@DELETE
@Path("/{productId}")
public Product deleteProduct(@PathParam("productId") long pid) {
	return productService.removeProduct(pid);
}

}

package org.dinesh.softarica.productService.resources.bean;

ProductFilterBean.java public class ProductFilterBean {

private @QueryParam("year") int year;
private @QueryParam("start") int start;
private @QueryParam("size") int size;

public int getYear() {
	return year;
}
public void setYear(int year) {
	this.year = year;
}
public int getStart() {
	return start;
}
public void setStart(int start) {
	this.start = start;
}
public int getSize() {
	return size;
}
public void setSize(int size) {
	this.size = size;
}

}

Result:

The annotation we have used is:
@Path(“/products”)

on the top level of the class named ProductResource which contains method getProduct and annotated with @GET

URL to check result:

http://localhost:8080/productService/webapi/products/

Output is observed using Tool POSTMAN:

By choosing GET operation see the list of products:

Filtering: Lets Filter the product based on year: 2016

Filtering: But if we search product for year 2015 then we don't get any because there are no any product created in 2015.

Pagination: start=0 & size=1

Pagination: start=0 & size=2

Pagination: start=1 & size=1

Download: Source Code

⚠️ **GitHub.com Fallback** ⚠️