In this tutorial, you will learn developing a RESTful web services API for CRUD operations (Create, Retrieve, Update and Delete), which corresponding to standard HTTP methods POST, GET, PUT and DELETE, using Jersey – an open source REST framework and implementation of JAX-RS (Java API for RESTful Web Services) specification.

To follow this tutorial, suppose that you’re familiar with Java web development using Eclipse IDE, Maven build and Apache Tomcat server. Better if you completed this Hello world RESTful tutorial for beginner.

And make sure that you have the latest versions of Java Development Kit (JDK), Eclipse and Tomcat installed on your computer. In this tutorial, I use JDK 11, Eclipse 2019-09 and Tomcat 9.0. Also you need to have curl program to test the webservices.

 

1. Configure Java Dynamic Web Project for RESTful Web Services with Jersey

Add the following dependencies into your project’s pom.xml file:

<dependency>
	<groupId>org.glassfish.jersey.containers</groupId>
	<artifactId>jersey-container-servlet</artifactId>
	<version>2.29.1</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.inject</groupId>
	<artifactId>jersey-hk2</artifactId>
	<version>2.29.1</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.media</groupId>
	<artifactId>jersey-media-json-jackson</artifactId>
	<version>2.29.1</version>
</dependency>
The first dependency is for Jersey container servlet that processes requests for RESTful webservices. The second one is for an injection library required by Jersey. And the third one is for processing data in JSON format (convert Java objects to JSON and vice-versa). The version 2.29.1 (or newer) works well on JDK 8 or newer (tested with JDK 11).

Then open the web.xml file and insert the following code:

<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>net.codejava.ws</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>
This is to specify Jersey Container servlet is responsible to handle all requests coming to the web application with URL starts with /rest/ (after the webapp’s context path). We also specify the package net.codejava.ws contains RESTful webservices classes to be exposed to the clients.

 

2. Code Domain Model Class



We will develop RESTful webservices API that allow clients to do CRUD operations on products, so create a domain model class as simple as follows:

package net.codejava.ws;

public class Product {
	private int id;
	private String name;
	private float price;

	public Product(int id) {
		this.id = id;
	}

	public Product() {
	}

	public Product(int id, String name, float price) {
		this.id = id;
		this.name = name;
		this.price = price;
	}

        // getters and setters are not shown for brevity

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Product other = (Product) obj;
		if (id != other.id)
			return false;
		return true;
	}	
}
As you can see, in this model class we implement equals()and hashCode() based on product ID so a Product object can be found in an ArrayList as shown below in the DAO class.


3. Code DAO Class

For the shake of simplicity, I don’t use a real database. Instead, I code a DAO class with some mock data so we can focus on the RESTful webservices methods for CRUD operations. Create the ProductDAO class with the following code:

package net.codejava.ws;

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

public class ProductDAO {
	private static ProductDAO instance;
	private static List<Product> data = new ArrayList<>();
	
	static {
		data.add(new Product(1, "iPhone X", 999.99f));
		data.add(new Product(2, "XBOX 360", 329.50f));		
	}
	
	private ProductDAO() {
		
	}
	
	public static ProductDAO getInstance() {
		if (instance == null) {
			instance = new ProductDAO();
		}
		
		return instance;				
	}
	
	public List<Product> listAll() {
		return new ArrayList<Product>(data);
	}
	
	public int add(Product product) {
		int newId = data.size() + 1;
		product.setId(newId);
		data.add(product);
		
		return newId;
	}
	
	public Product get(int id) {
		Product productToFind = new Product(id);
		int index = data.indexOf(productToFind);
		if (index >= 0) {
			return data.get(index);
		}
		return null;
	}
	
	public boolean delete(int id) {
		Product productToFind = new Product(id);
		int index = data.indexOf(productToFind);
		if (index >= 0) {
			data.remove(index);
			return true;
		}
		
		return false;
	}
	
	public boolean update(Product product) {
		int index = data.indexOf(product);
		if (index >= 0) {
			data.set(index, product);
			return true;
		}
		return false;
	}
}
As you can see, this DAO class implements CRUD operations to manage products. It will be used by RESTful web services class in the next section below.

 

Spring Boot REST APIs Ultimate Course 

Hands-on REST API Development with Spring Boot: Design, Implement, Document, Secure, Test, Consume RESTful APIs

 

4. Code CRUD RESTful Web Services Class

Now, let’s code a RESTful webservices class that provides REST API for the clients. Write the initial code as below:

package net.codejava.ws;

import java.net.*;
import java.util.*;

import javax.ws.rs.*;
import javax.ws.rs.core.*;


@Path("/products")
public class ProductResource {
	private ProductDAO dao = ProductDAO.getInstance();
	
	// RESTful API methods go here...	
	
}
Then write code to implement API method for each operation in the CRUD.\

 

Code RESTful API method for Retrieval (list all items):

Put the following method in to the ProductResource class:

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Product> list() {
	return dao.listAll();
}
This method serves HTTP GET request and returns a list of products in JSON format. Type the following command to test with curl:

curl http://localhost:8080/MyWebsite/rest/products
Response from the server:

[{"id":1,"name":"iPhone X","price":999.99},{"id":2,"name":"XBOX 360","price":329.5}]
NOTE: The best practice for this retrieval operation is returning HTTP status code 204 No Content if no data in the response. Hence update the code as below:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response list() {
	List<Product> listProducts = dao.listAll();
	
	if (listProducts.isEmpty()) {
		return Response.noContent().build();
	}
	
	return Response.ok(listProducts).build();
}
 

Code RESTful API method for Retrieval (get a specific item):

Add the following method to the ProductResource class:

@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("id") int id) {
	Product product = dao.get(id);
	if (product != null) {
		return Response.ok(product, MediaType.APPLICATION_JSON).build();
	} else {
		return Response.status(Response.Status.NOT_FOUND).build();
	}
}
This method returns information of a particular product based on a given product ID. If a product is found, it returns the response with HTTP 200 status and includes JSON data of the product. Command to test:

curl http://localhost:8080/MyWebsite/rest/products/2
Response from the server:

{"id":2,"name":"XBOX 360","price":329.5}
 

Code RESTful API method for Create (add a new item):

Put the following code that exposes an API method allowing the client to add a new product:

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response add(Product product) throws URISyntaxException {
	int newProductId = dao.add(product);
	URI uri = new URI("/products/" + newProductId);
	return Response.created(uri).build();
}
As you can see, this method serves HTTP POST request and requires content type of JSON posted from the client. It returns a Response object with HTTP 201 (Created) status and the URI of the newly added item. Run the following command to test (type all in one line):

curl -v -X POST -H "Content-Type: application/json"
-d "{\"name\":\"MacBook\",\"price\":1000}" 
http://localhost:8080/MyWebsite/rest/products/
The server’s response includes something like this:

HTTP/1.1 201
Location: http://localhost:8080/products/3
Content-Length: 0
 

Code RESTful API method for Update (update an existing item):

The following method exposes a RESTful API that allows the client to update a product with a given ID:

@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("{id}")
public Response update(@PathParam("id") int id, Product product) {
	product.setId(id);
	if (dao.update(product)) {
		return Response.ok().build();
	} else {
		return Response.notModified().build();
	}
}
As you can see, this method requires HTTP PUT method and application/json content type. ID of the product is passed as a path parameter in the request URI. If the product is update successfully, return HTTP 200 (OK) status. Else if the product is not found, return HTTP 304 (Not Modified) status.

Run this command to update the product with ID 1:

curl -v -X PUT -H "Content-Type: application/json" 
-d "{\"name\":\"iPad\",\"price\":888}" 
http://localhost:8080/MyWebsite/rest/products/1
You can see the following information in the server’s response:

HTTP/1.1 200
Content-Length: 0
If you try to update a product with non-exist ID, the server will return this response:

HTTP/1.1 304
 

Code RESTful API method for Delete (remove an item):

And the following method allows the client to delete a product by ID:

@DELETE
@Path("{id}")
public Response delete(@PathParam("id") int id) {
	if (dao.delete(id)) {
		return Response.ok().build();
	} else {
		return Response.notModified().build();
	}
}
You see, this method requires HTTP DELETE method with ID of the product as a path parameter in the request URI. If the product is removed successfully, the server returns HTTP 200 (OK) status; else returns HTTP 304 (Not Modified) status.

Type the following command to test:

curl -v -X DELETE http://localhost:8080/MyWebsite/rest/products/2
This will remove the product with ID 2.

NOTE: the best practice for delete operation if successful is returning HTTP status code 204 No Content. So update the code as below:

if (dao.delete(id)) {
	return Response.noContent().build();
}
  

5. Code RESTful Web Services Client Program

In this section, I will guide you how to code a client program to consume RESTful web services using Jersey Client API. Create a new client project and add the following dependencies to the pom.xml file:

<dependency>
	<groupId>org.glassfish.jersey.core</groupId>
	<artifactId>jersey-client</artifactId>
	<version>2.29.1</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.inject</groupId>
	<artifactId>jersey-hk2</artifactId>
	<version>2.29.1</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.media</groupId>
	<artifactId>jersey-media-json-jackson</artifactId>
	<version>2.29.1</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jaxb</groupId>
	<artifactId>jaxb-runtime</artifactId>
	<version>2.3.2</version>
</dependency>
Write initial code for the client program as follows:

package net.codejava.ws;

import javax.ws.rs.client.*;
import javax.ws.rs.core.*;

import org.glassfish.jersey.client.ClientConfig;

public class ProductClientTest {
	private static String baseURI = "http://localhost:8080/MyWebsite/rest/products";

	static WebTarget getWebTarget() {
		ClientConfig config = new ClientConfig();
		Client client = ClientBuilder.newClient(config);
		
		return client.target(baseURI);		
	}
	
	public static void main(String[] args) {
		// call a test method: testList(), testAdd(), testGet()...
	}

}
To test listing all items, code the following method:

static void testList() {
	WebTarget target = getWebTarget();
	
	String response = target.request().accept(MediaType.APPLICATION_JSON).get(String.class);
	
	System.out.println(response);		
}
 

Test to get a specific item by ID:

static void testGet() {
	WebTarget target = getWebTarget();
	String productId = "3";
	Product product = target.path(productId)
				.request().accept(MediaType.APPLICATION_JSON)
				.get(Product.class);
	
	System.out.println(product);		
}
 

Test to add a new item:

static void testAdd() {
	WebTarget target = getWebTarget();
	Product product = new Product("ZenFoneX", 888.88f);
	Response response = target.request()
			.post(Entity.entity(product, MediaType.APPLICATION_JSON), Response.class);
	
	System.out.println(response.getLocation().toString());
}
 

The following method tests updating an item:

private static void testUpdate() {
	WebTarget target = getWebTarget();
	Product product = new Product("ZenFoneX", 100f);
	String productId = "4";
	Response response = target.path(productId).request()
			.put(Entity.entity(product, MediaType.APPLICATION_JSON), Response.class);
	System.out.println(response);		
}
 

And code the method that tests deleting an item as follows:

private static void testDelete() {
	WebTarget target = getWebTarget();
	String productId = "3";
	Response response = target.path(productId).request()
			.delete(Response.class);
	System.out.println(response);		
}
That’s how to code a RESTful webservices client program to test CRUD operations.

So far you have learned how to code a RESTful webservices application with CRUD (Create, Retrieve, Update and Delete) operations. I hope you found this tutorial helpful. And for your reference, you can download the sample project in the attachments section below. You can also get code from GitHub here.

You can also watch the video version below:

 

What's Next? I recommend you follow this one: Spring Boot Hello World RESTful Web Services Tutorial

 

Recommended Course:

 

Other Java Web Services Tutorial:

 

Spring-based Web Services and REST API Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Attachments:
Download this file (JavaCrudRestfulWS.zip)JavaCrudRestfulWS.zip[Java CRUD RESTful Web Services Sample Projects]30 kB

Add comment

   


Comments 

#9Yassine2023-05-15 16:08
Thanks for all effort
Quote
#8gültekin2023-04-29 08:31
heloo thankyou for codes
Quote
#7Dave Garratt2022-09-06 09:58
If I wanted to extend your example so that it uses a database for CRUD - where would I put the JDBC connection code and would it establish a connection and close it again for each request ?
Quote
#6Himanshu Gupta2022-05-21 02:44
When I run curl for the first time after followed every step in this video, I get html text with http status 404 in the terminal, anyone facing the same problem and resolve it? please help.
Quote
#5eris2021-09-05 06:49
when i run curl for the first time after follwed every step in this video, i get html text with http status 404 in the terminal, anyone facing the same problem and resolve it? please help
Quote