Srikanth Technologies

CRUD operations with Restful service in Java

In this blog, I create a Restful service in Java to perform all CRUD (Create, Read, Update and Delete) operations typically supported by Restful service.

I use Jersey, which is RI of JAX-RS. I placed all .jar files related to Jersey project in /WEB-INF/lib folder.

In order to use Jersey, we need to add the following entries to web.xml. We need to register a servlet provided by Jersey and provide the package name (restdemo) in which our restful service is placed.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>Restful crud</display-name>
   <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>restcrud</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>books.html</welcome-file>
  </welcome-file-list>
</web-app>

In order to keep code simple, I used a collection to represent data instead of a Database. Should we ever wish you use a database we need to change code in Restful Service accordingly. The overall concept of this blog remains the same.

The following classes are used by Restful service.

Book.java

This represents a book. It contains three properties - id, title and price.

package restcrud;
 
public class Book {
	private int id;
	private String title;
	private double price;
	public Book() {
	}
	public Book(int id, String title, double price) {
		super();
		this.id = id;
		this.title = title;
		this.price = price;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ", title=" + title + ", price=" + price + "]";
	}
}

Books.java

This class contains a collection of Book objects. It is our repository of books. It uses Streams and Lambda expressions of Java8. In case you are not familiar with them, please read my blog on that topic. Of course, we can refactor the code to use only simple collections.
package restcrud;

import java.util.ArrayList;
import java.util.List;

public class Books {
	private static ArrayList<Book> books = new ArrayList<>();
        // static initializer called when class is loaded
	static {   
		books = new ArrayList<>();
		books.add(new Book(1, "The Outliers", 500));
		books.add(new Book(2, "World Is Flat", 550));
	}
	public static List<Book> getBooks() {
		return books;
	}
	public static int getNextId() {
		return books.stream().mapToInt( b -> b.getId()).max().getAsInt() + 1;
	}
}

BooksService.java

This is Restful service that is used when a request with /books is made from client.

It supports GET, PUT, POST and DELETE methods of Http request. It throws necessary exceptions whenever required.

I used Google's Gson library to convert Java objects to JSON. There are other options in this regards, but I feel Gson is very easy to use and it needs only one .jar file to be placed in /WEB-INF/lib folder.

You can download Gson from maven central.

package restcrud;

import java.util.List;
import java.util.Optional;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.google.gson.Gson;

@Path("/books")
public class BooksService {
	List<Book> books;

	public BooksService() {
		books = Books.getBooks();
	}

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public String getBooks() {
		Gson gson = new Gson();
		return gson.toJson(books);
	}

	@Path("{id}")   // Example url is /books/1
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public String getBook(@PathParam("id") int id) {
                // look for a book with the given id in books collection using stream and lambda expression
                // Optional is new concept in Java8. It optionally represents an object. 
                // Method isPresent() is used to determine whether it represents an object or null
		Optional <Book> book = books.stream().filter(b -> b.getId() == id).findAny();
		if (!book.isPresent())
			throw new NotFoundException(); // sends 404 to client 
		Gson gson = new Gson();
		return gson.toJson(book.get());
	}

	@PUT
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public void updateBook(@FormParam("id") int id, @FormParam("price") double price) {
		Optional<Book> book = books.stream().filter(b -> b.getId() == id).findAny();
		if (!book.isPresent())
			throw new NotFoundException();

		book.get().setPrice(price);
	}

	@DELETE
        @Path("{id}")
	public void deleteBook(@PathParam("id") int id) {
		 for(Book b : books) {
			 if ( b.getId() == id) {
				 books.remove(b);
				 return;
			 }
		 }

		 // if no book is found then throw exception 
                 throw new NotFoundException();
	}

	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public void addBook(@FormParam("title") String title, @FormParam("price") double price) {
		int id = Books.getNextId();
		Book book = new Book(id, title, price);
		books.add(book);
	}
}

Client Code

Once server is up and running then the following client will allow you to perform all basic operations supported by Restful service using a simple html page using jQuery to make AJAX requests.

books.html

Make sure you include jquery.js in root folder of your web application (WebContent in case of Eclipse). I downloaded jQuery from jquery.com and renamed the file to jquery.js.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Books Client</title>
<script type="text/javascript" src="jquery.js">
</script>
<script>
  $(document).ready( 
	function() {
             $.getJSON("rest/books",{}, showBooks);
	}
  );

  function showBooks(books) {
     $.each(books, 
    	 function(idx,book) 
    	 {
    	    $("#books").append("<li>" + book.id + " - " + book.title + " - " +  book.price + "</li>");
         }
     );
  }

  function updatePrice() {
    
     $.ajax( 
	    	 {
		       url : "rest/books/" +  $("#id").val(),
      	       data : {"price": $("#newprice").val()},
		       method : "PUT",
		       complete : showUpdateResult
	    	 }
	      ); 
  }

  
  function showUpdateResult(result) {
		 if (result.status == 200)
		    alert("Updated Successfully");
		 else
		    alert("Sorry! Could not update book!");
  }

  function deleteBook() {
	     $.ajax( 
	    	 {
		       url : "rest/books/" + $("#id").val(),
   	  	       method : "delete",
		       complete : showDeleteResult
	    	 }
	      );
  }

	  
  function showDeleteResult(result) {
		 if (result.status != 404)
		    alert("Deleted Successfully");
		 else
		    alert("Sorry! Could not delete book!");
  }
	
  function addBook() {
	     $.ajax( 
	    	 {
		       url : "rest/books",
      	               data : { "title" : $("#title").val(), "price": $("#price").val()},
		       method : "POST",
		       complete : showAddResult
	    	 }
	      );
  }
    	  
  function showAddResult(result) {
		 alert("Added Successfully");
  }
	  
</script>
</head>
<body>
	<h2>Books</h2>
	<ul id="books">
	</ul>

	<h3>Update or Delete Book</h3>
	Book Id
	<br />
	<input type="text" id="id" /> 
	<button onclick="deleteBook()">Delete </button>
	<p />
	Price
	<br />
	<input type="text" id="newprice" />
	<p />
	<button onclick="updatePrice()">Update Price</button>

	<h3>Add Book</h3>
	Title
	<br />
	<input type="text" id="title" />
	<p />
	Price
	<br />
	<input type="text" id="price" />
	<p />
	<button onclick="addBook()">Add Book</button>
</body>
</html>

Run this page and test all operations related to Restful Service.