Rest using Jersey – Complete Tutorial with JAXB, Exception Handling and Client Program

Recently I started working on a Restful web service project using Jersey API. There are some tutorials available online but I faced some issues with exception handling and I didn’t found anywhere complete project using JaxB and providing exception handling approach. So once I was able to create a Restful web service using Jersey API with exception handling and client program, I decided to write this tutorial to help everyone getting started with Jersey.

Who Should Use This Tutorial

This tutorial is intended for Java programmers who are interested in developing and deploying Restful Web Services using Jersey API and JaxB.

Prerequisites

The scope of this tutorial is to use Jersey API for creating Restful web services and invoking the web service using Java client program and testing web service using tool. Basic understanding of Java, Web Services, XML, Maven and any application server (JBoss/Tomcat) is required to understand the tutorial with ease.

Softwares and Tools used

  • JDK version 1.6.0_37
  • Apache Maven 3.0.3
  • Mac OS X 10.8.2
  • JBoss 4.2.2 (You can use any application server like Tomcat, Glassfish etc.)
  • Eclipse Indigo (Any Java IDE with Maven support)

Creating Maven Project in Eclipse and Jersey

Create a maven project in Eclipse and it will provide you with basic project structure. I have given GroupId as “JD” and artifactID as “my-jersey-project” but you can give anything you like. Once we complete the development of our project, it will look like below in the image.


 
Jersey Web service project explanation

pom.xml: Project configuration details, note the jersey dependencies provided, other details are common for any maven project.

<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>JD</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>${artifactId}-${version}</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1-alpha-2</version>
				<configuration>
					<packagingExcludes>
						WEB-INF/lib/servlet-api-*.jar
				</packagingExcludes>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<version>2.0</version>
				<executions>
					<execution>
						<id>unpack</id>
						<phase>install</phase>
						<goals>
							<goal>unpack</goal>
						</goals>
						<configuration>
							<artifactItems>
								<artifactItem>
									<groupId>${groupId}</groupId>
									<artifactId>${artifactId}</artifactId>
									<version>${version}</version>
									<type>${packaging}</type>
									<overWrite>true</overWrite>
									<outputDirectory>${project.build.directory}/${artifactId}-${version}-exploded.${packaging}</outputDirectory>
								</artifactItem>
							</artifactItems>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

EmpRequest.java: Java Bean for the request object. The important thing to note here is @XmlRootElement annotation to map the class to an XML element.

package com.jd.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;
	}
}

EmpResponse.java: Java bean for the response object.

package com.jd.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;
	}

}

ErrorResponse.java: Java Bean that will be send as response incase of exception.

package com.jd.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;
	}

}

EmpNotFoundException.java: A normal exception class thrown in the web service.

package com.jd.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);
	}
}

jboss-web.xml: To define JBoss servlet context for the web service.

<jboss-web>
   <context-root>jd</context-root>
</jboss-web>

web.xml: Deployment descriptor for the web service. So any request with URI “http://<HOST>:<POST>/jd/rest/*” will be processed by Jersey ServletContainer servlet. Important thing to note is the init-param value passed for “com.sun.jersey.config.property.packages”. This defines in which 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 id='WebApp_ID' version='2.5'
	xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
	xsi:schemaLocation='http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd'>

	<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.jd</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>

EmpRouter.java: Resource class handling different kinds of request.

  • @Path(“/emp”) – All the requests with URI http://<HOST>:<PORT>/jd/rest/emp/ will be processed by this resource class.
  • @Path(“/getEmp”) – All the requests with URI http://<HOST>:<PORT>/jd/rest/emp/getEmp will be processed by this method.
  • @POST – This annotation defines that the HTTP method used should be POST. Some other possible values are @GET, @PUT, @DELETE
  • @Consumes(MediaType.APPLICATION_XML) – The method accepts XML element
  • @Produces(MediaType.APPLICATION_XML) – The method returns XML element
package com.jd.router;

import com.jd.exception.EmpNotFoundException;
import com.jd.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();
	}
}

EmpNotFoundExceptionMapper.java: Exception Mapper class that maps EmpNotFoundException to Response object. The class should have annotation @Provider. 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.jd.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.jd.exception.EmpNotFoundException;
import com.jd.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 in the application server.

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.jd.client;

import javax.ws.rs.core.MediaType;

import com.jd.model.EmpRequest;
import com.jd.model.EmpResponse;
import com.jd.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 = 'http://localhost:8080/jd/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());
		}
	}

}

I hope the tutorial is easy enough to follow and write your first Restful web service using Jersey.
Please let me know if you face any issues or need further explanations.
 

Reference: Rest using Jersey – Complete Tutorial with JAXB, Exception Handling and Client Program from our JCG partner Pankaj Kumar at the Developer Recipes blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

One Response to "Rest using Jersey – Complete Tutorial with JAXB, Exception Handling and Client Program"

  1. Majid says:

    HI,
    Thank you for this tutorial, can you please post or send me the source code ?
    If I want to use Tomcat instead of Jboss, should I just ignore jboss-web.xml ?
    thanks, your help is appreciated.

Leave a Reply


− 4 = two



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books