Restful Web Services in Java using Jersey


JAX-RS-(RESTful Web Services ) is the Java API for creating REST web services. JAX-RS uses annotations to simplify the development and deployment of web services. JAX-RS is part of JDK, so you don’t need to include anything to use it’s annotations.

Some of the important JAX-RS annotations are:
  • @Path:used to specify the relative path of class and methods. We can get the URI of a webservice by scanning the Path annotation value.
  • @GET.@PUT,@POST,@DELETE and @HEAD:used to specify the HTTP request type for a method.
  • @Produces,@Consumes:used to specify the request and response types.
  • @Consumes(MediaType.APPLICATION_JSON ) The method accepts JSON element.
  • @Produces(MediaType.APPLICATION_JSON ) The method returns JSON element.
  • @PathParam:used to bind the method parameter to path value by parsing it.

Restful Web Services and SOAP:

  1. SOAP is a protocol whereas REST is an architectural style.
  2. SOAP server and client applications are tightly coupled and bind with the WSDL(Web Services Description Language) contract whereas there is no contract in REST web services and client.
  3. Learning curve is easy for REST when compared to SOAP web services.
  4. REST web services request and response types can be XML, JSON, text etc. whereas SOAP works with XML only.
  5. JAX-RS is the Java API for REST web services whereas JAX-WS is the Java API for SOAP web services.
There are two major implementations of JAX-RS API.
    1.Jersey:Jersey is the reference implementation provided by Sun. For using Jersey as our JAX-RS implementation, all we need to configure its servlet in web.xml and add required dependencies. Note that JAX-RS API is part of JDK not Jersey, so we have to add its dependency jars in our application.
    2.RESTEasy: RESTEasy is the JBoss project that provides JAX-RS implementation.

Create Restful web service using Jersey and use Chrome Postman extension to test these.

Jersey Rest Web Service:

Create a dynamic web project and then convert it to Maven to get the skeleton of your web services project. Below image shows the project structure of the final project.


























Let’s look at the Jersey dependencies we have in pom.xml file.

<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>jersey-json</groupId>
<artifactId>jersey-json</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- Adding dependencies -->
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Now let’s look at the deployment descriptor to learn how to configure Jersey to create our web application.

Web.xml:


<?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" id="WebApp_ID" version="3.1">
<display-name>jersey-json</display-name>
<!-- Jersey Servlet configurations -->
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mouri</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Jersey Servlet configurations -->
</web-app>

So any request with URI "http://localhost:port/project-name/*" will be processed by Jersey ServletContainer servlet.

The value of init parameter com.sun.jersey.config.property.packages to provide package that will be scanned for web service resources and methods.

In this project we will create two model beans –Employee for our application data and Response for sending response to client systems. Since we will be sending JSON response.

Employee.java:

package com.mouri.json.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employee")
public class Employee {
private String name;
private int age;
private int id;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Override
public String toString() {
return id + "::" + name + "::" + age;
}

}


Response.java:

package com.mouri.json.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Response {
private boolean status;
private String message;
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}


Based on our URI structure, below is the service interface and it’s implementation code.

EmployeeService.java:

package com.mouri.json.service;

import com.mouri.json.model.Employee;
import com.mouri.json.model.Response;
public interface EmployeeService {
public Response addEmployee(Employee e);
public Response deleteEmployee(int id);
public Employee getEmployee(int id);
public Employee[] getAllEmployees();
}

EmployeeServiceImpl.java:

package com.mouri.json.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.mouri.json.model.Employee;
import com.mouri.json.model.Response;

@Path("/employee")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class EmployeeServiceImpl implements EmployeeService {

private static Map<Integer, Employee> employees = new HashMap<Integer, Employee>();

@Override
@POST
@Path("/add")
public Response addEmployee(Employee e) {
Response response = new Response();
if (employees.get(e.getId()) != null) {
response.setStatus(false);
response.setMessage("Employee Already Exists");
return response;
}
employees.put(e.getId(), e);
response.setStatus(true);
response.setMessage("Employee created successfully");
return response;
}

@Override
@GET
@Path("/{id}/delete")
public Response deleteEmployee(@PathParam("id") int id) {
Response response = new Response();
if (employees.get(id) == null) {
response.setStatus(false);
response.setMessage("Employee Doesn't Exists");
return response;
}
employees.remove(id);
response.setStatus(true);
response.setMessage("Employee deleted successfully");
return response;
}

@Override
@GET
@Path("/{id}/get")
public Employee getEmployee(@PathParam("id") int id) {
return employees.get(id);
}

@GET
@Path("/{id}/getDummy")
public Employee getDummyEmployee(@PathParam("id") int id) {
Employee e = new Employee();
e.setAge(99);
e.setName("Dummy");
e.setId(id);
return e;
}

@Override
@GET
@Path("/getAll")
public Employee[] getAllEmployees() {
Set<Integer> ids = employees.keySet();
Employee[] e = new Employee[ids.size()];
int i = 0;
for (Integer id : ids) {
e[i] = employees.get(id);
i++;
}
return e;
}

}


That’s it. Our web service is ready, just export it as WAR file and put it inside Tomcat webapps directory or deploy into any other container of your choice.
Below are some of the tests performed using Postman chrome extension for this web service. Note that we have to provide Accept and Content-Type values as “application/json” in request header as shown in below image.



getDummy:



add:







get:


getAll:



delete:



That’s all for creating web services using Jersey JAX-RS implementation. As you can see that most of the code is using JAX-RS annotations and Jersey is plugged in through deployment descriptor and dependencies.

Thanks & Regards,
Prabhakar Reddy Naguru,
Developer Trainee,
MOURI Tech PVT LTD.
http://www.mouritech.com.

Comments