Welcome to Java Jersey Tutorial. Recently I started working on a Restful web service project using the JAX-RS Jersey framework.
Java Jersey project tracks the JAX-RS API, which is used to create Restful web services in Java.
This tutorial is intended for Java programmers who are interested in developing and deploying Restful Web Services using JAX-RS API and JAXB.
The scope of this tutorial is to use Jersey API for creating Restful web services and invoking the web service using a Java client program and testing web service using the tool. Basic understanding of Java, Web Services, XML, Maven, and any application server (JBoss/Tomcat) is required to understand the tutorial with ease.
Create a “Dynamic Web Project” in Eclipse and then convert it to the maven project. This will provide us a maven based web application basic project. I have given GroupId as com.journaldev.jersey
and artifactID as my-jersey-project
but you can specify anything you like. Once we complete the development of our project, the project structure will look like the below image.
1. pom.xml: Project configuration details, note the jersey dependencies provided, other details are common for any similar maven project.
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.jersey</groupId>
<artifactId>my-jersey-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.14</version>
</dependency>
</dependencies>
<build>
<finalName>My-Jersey-Project</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. EmpRequest.java: Java Bean for the request object. The important thing to note here is the @XmlRootElement
annotation to map the class to an XML element.
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "empRequest")
public class EmpRequest {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3. EmpResponse.java: Java bean for the response object.
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "empResponse")
public class EmpResponse {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4. ErrorResponse.java: Java Bean that will be sent as the response in case of an exception.
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "errorResponse")
public class ErrorResponse {
private String errorCode;
private int errorId;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public int getErrorId() {
return errorId;
}
public void setErrorId(int errorId) {
this.errorId = errorId;
}
}
5. EmpNotFoundException.java: A normal exception class thrown in the web service.
package com.journaldev.exception;
public class EmpNotFoundException extends Exception {
private static final long serialVersionUID = 4351720088030656859L;
private int errorId;
public int getErrorId() {
return errorId;
}
public EmpNotFoundException(String msg, int errorId) {
super(msg);
this.errorId = errorId;
}
public EmpNotFoundException(String msg, Throwable cause) {
super(msg, cause);
}
}
6. web.xml: Deployment descriptor for the web service. So any request with URI https://<HOST>:<PORT>/My-Jersey-Project/rest/*
will be processed by Jersey ServletContainer servlet. The init-param value passed for “com.sun.jersey.config.property.packages” defines the package jersey will look for the web service classes. This property must point to your resources classes. It also looks for the resource classes into the sub-packages.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns="https://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>My Jersey Project</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.journaldev</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>
<!-- Jersey Servlet configurations -->
</web-app>
7. EmpRouter.java: Resource class handling different kinds of request.
https://<HOST>:<PORT>/My-Jersey-Project/rest/emp/
will be processed by this resource class.https://<HOST>:<PORT>/My-Jersey-Project/rest/emp/getEmp
will be processed by this method.package com.journaldev.router;
import com.journaldev.exception.EmpNotFoundException;
import com.journaldev.model.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBElement;
@Path("/emp")
public class EmpRouter {
@POST
@Path("/getEmp")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Response getEmp(JAXBElement<EmpRequest> empRequest)
throws EmpNotFoundException {
EmpResponse empResponse = new EmpResponse();
if (empRequest.getValue().getId() == 1) {
empResponse.setId(empRequest.getValue().getId());
empResponse.setName(empRequest.getValue().getName());
} else {
throw new EmpNotFoundException("Wrong ID", empRequest.getValue()
.getId());
}
return Response.ok(empResponse).build();
}
}
8. EmpNotFoundExceptionMapper.java: Exception Mapper class that maps EmpNotFoundException to Response object. The class should have @Provider annotation. This class should be in the package provided for resource classes in web.xml. Implementation of toResponse()
method generates the ErrorResponse object and set it as Entity in Response object with status as INTERNAL_SERVER_ERROR.
package com.journaldev.exceptionmapper;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import com.journaldev.exception.EmpNotFoundException;
import com.journaldev.model.ErrorResponse;
@Provider
public class EmpNotFoundExceptionMapper implements
ExceptionMapper<EmpNotFoundException> {
public EmpNotFoundExceptionMapper() {
}
public Response toResponse(
EmpNotFoundException empNotFoundException) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrorId(empNotFoundException.getErrorId());
errorResponse.setErrorCode(empNotFoundException.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
errorResponse).type(
MediaType.APPLICATION_XML).build();
}
}
Our web service is ready, just build it to create the WAR file and deploy it to the application server.
We can use the Jersey Client to call our web service and get a response programmatically. EmpClient.java: This is a sample java program through which are invoking our web service. We are using Jersey Client API to invoke the service and based on response status we are parsing response entity to EmpResponse or ErrorResponse class.
package com.journaldev.client;
import javax.ws.rs.core.MediaType;
import com.journaldev.model.EmpRequest;
import com.journaldev.model.EmpResponse;
import com.journaldev.model.ErrorResponse;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class EmpClient {
/**
* @param args
*/
public static void main(String[] args) {
String uri = "https://localhost:8080/My-Jersey-Project/rest/emp/getEmp";
EmpRequest request = new EmpRequest();
// set id as 1 for OK response
request.setId(2);
request.setName("PK");
try {
Client client = Client.create();
WebResource r = client.resource(uri);
ClientResponse response = r.type(MediaType.APPLICATION_XML).post(ClientResponse.class, request);
System.out.println(response.getStatus());
if (response.getStatus() == 200) {
EmpResponse empResponse = response.getEntity(EmpResponse.class);
System.out.println(empResponse.getId() + "::" + empResponse.getName());
} else {
ErrorResponse exc = response.getEntity(ErrorResponse.class);
System.out.println(exc.getErrorCode());
System.out.println(exc.getErrorId());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
Success Response Error Response
In this post, we learned how to create a REST web service using Jersey API. We also looked into the Jersey Client to invoke our REST APIs through java program.
You can checkout complete project code from our GitHub Repository.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
In the client when i call ErrorResponse exc = response.getEntity(ErrorResponse.class); i get the following stack trace. Any ideas? [org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Premature end of file.] at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:108) at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:549) at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:519) at ie.netelek.assets.ws.intf.AssetService.populateCombos(AssetService.java:85) at ie.netelek.assets.add.AddAssetController.populateCombos(AddAssetController.java:181) at ie.netelek.assets.add.AddAssetController.initialize(AddAssetController.java:126) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2152) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2028)
- Alan
Brilliant and simple tutorial on implementing a basic RESTful service that connects all the dots…
- K
Pankaj, How does the client know about the EmpRequest, EmpResponse and ErrorResponse classes ? Do we have to copy them from the service side to the client side (similar to how it is done in SOAP WS where the required classes are generated from the WSDL using wsgen utility) ? Can you please clarify ? Thanks
- K
Hi Pankaj, Thanks for the wonderful post. I have my own webservice implementation using jersey client. I have made it secure using the BASIC authentication. It works good but my requirement is to customize the 401 Unauthorized error the validationError XML which I generate in other business errors. Is there any way that we can customize 401 Unauthorized error? Right now if the Auth constraints are invalid, the request does not come to any of the classes in my application. Any help would be appreciated. Thanks in the anticipation. Regards, Amishi
- Amishi Shah
thank a lot for your useful tutorial.
- mahta
what is the mostly used API in the industry
- Nagaraju
Can we use any API at Client side
- Nagaraju
If you ever come to Portugal i will buy you a beer… even if i need to go across the entire country lol
- Tiago Cabral
The content and the collection of questions on your website is amazing. Please provide some interview questions on SOAP and REST webservices.
- Kavya Jindal
Pankaj, Excellent and brief content about REST webservices. Can you please explain about SOAP, WSDL also. Thanks, Sowmya
- Sowmya