Thursday, December 23, 2010

Writing JAX-RS REST API Server with Jersey / GlassFish v3

Writing REST API Web Service application in Java EE 6 is now trivial with JAX-RS API and Jersey (the reference implementation of JAX-RS, bundled with GlassFish v3). I'll show you how, with raw real code. ;-)


  1. Eclipse IDE, pick the Java EE edition. Latest version is 3.6 SR1 (Helios)
  2. JBoss Tools plugin for Eclipse IDE (probably optional)
  3. A Java EE 6 Server like GlassFish v3 or JBoss AS 6 (not GA yet)

Create the Web (WAR) Project

Create a new Dynamic Web project in Eclipse.

You'll need to choose a Java EE container runtime, it will download the libraries ("Java EE 6 SDK") as well.

Implement the Resource Class

Create a new JAX-RS resource class. What makes it a resource class is you sprinkle it with annotation.

I use JBoss Tools and GlassFish server plugin for Eclipse so either or both of them adds the Java EE libraries to my build path, including the most important  here is jsr311-api.jar. If you use Maven you can depend on artifact.
A sample resource class is like below. Note that I split my resource class to interface and implementation class.

package com.abispulsa.bisnis.service;


import org.eclipse.emf.ecore.EObject;

* <!-- begin-user-doc -->
* A representation of the model object '<em><b>Refiller</b></em>'.
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Refill the target mobile number by some amount.
* This is the public facing REST API.
* <!-- end-model-doc -->
* <p>
* The following features are supported:
* <ul>
*   <li>{@link com.abispulsa.bisnis.service.Refiller#getSession <em>Session</em>}</li>
* </ul>
* </p>
* @see com.abispulsa.bisnis.service.ServicePackage#getRefiller()
* @model
* @generated
public interface Refiller extends EObject {

* <!-- begin-user-doc -->
* This actually only queues it. The real work is done in the queue processor job.
* <!-- end-user-doc -->
* @model
* @generated
String refill(@FormParam("mobileNumber") String mobileNumber, @FormParam("voucherCode") String voucherCode);

} // Refiller

You may notice I'm using the mighty EMF to design the resource class. Yes, that's right! ;-)
(ok, so that's the excuse for me for posting this article to EclipseDriven, I'm hoping people will be curious "what's EMF? sounds cool!" hahahaha)

Ok so here's the actual resource class :

package com.abispulsa.bisnis.service.impl;


import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;

import com.abispulsa.bisnis.service.Refiller;
import com.abispulsa.bisnis.service.ServicePackage;
import com.abispulsa.bisnis.service.Session;

* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Refiller</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
*   <li>{@link com.abispulsa.bisnis.service.impl.RefillerImpl#getSession <em>Session</em>}</li>
* </ul>
* </p>
* @generated
public class RefillerImpl extends EObjectImpl implements Refiller {

* <!-- begin-user-doc -->
* Make it public constructor for used in JAX-RS.
* We should wrap it inside application and use CDI though.
* <!-- end-user-doc -->
* @generated NOT
public RefillerImpl() {

* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
public String refill(String mobileNumber, String voucherCode) {
return String.format("MobileNumber=%s voucherCode=%s", mobileNumber, voucherCode);

private void checkAuthentication() {
// TODO Auto-generated method stub



} //RefillerImpl

There are several things to notice here:

  1. The implementation resource class is @Path annotated. Of course, since you can't instantiate an interface!
  2. It's possible to "split" JAX-RS annotations between interface, class, interface methods and class method. In my example, the interface defines the the REST API and specific structure of the service. However, the implementation can decide where to put the service itself using @Path. The implementation do not override any of the JAX-RS annotations (REST API structure) defined by the interface.
  3. A public constructor is needed (EMF generated default constructor is protected, there is a reason why), because Jersey will instantiate the resource class directly. It's possible to implement so you can instantiate your resource classes yourself and configure Jersey for that. More on this later.

Configuring web.xml for Jersey

The last thing is you need to configure the Jersey servlet in your web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns=""





The web.xml above tells the Java EE 6 Container (i.e. GlassFish v3) to:

  1. Create a Jersey servlet at URL path: /api/v1
  2. Load JAX-RS resource classes from my package:
com.abispulsa.bisnis.service.impl init-param contains a comma-separated list of package names (so you can list multiple packages there). Note that this is optional. I use it because my Web/WAR project doesn't actually contain these packages, but the packages are provided by another JAR that I included in WEB-INF/lib. If your resource classes are inside the WAR itself (i.e. built to WEB-INF/classes) you can leave out that configuration and Jersey will find your classes just fine.

Deploy the Web Project

Deploying the app into GlassFish v3 outputs the following log:

INFO: Scanning for root resource and provider classes in the packages:
INFO: Root resource classes found:
  class com.abispulsa.bisnis.service.impl.RefillerImpl
INFO: No provider classes found.

INFO: GlobalStatsProvider registered
INFO: Initiating Jersey application, version 'Jersey: 1.1.5 01/20/2010 04:04 PM'
INFO: Adding the following classes declared in META-INF/services/jersey-server-components to the resource configuration:
  class com.sun.jersey.multipart.impl.FormDataMultiPartDispatchProvider
  class com.sun.jersey.multipart.impl.MultiPartConfigProvider
  class com.sun.jersey.multipart.impl.MultiPartReader
  class com.sun.jersey.multipart.impl.MultiPartWriter

INFO: Loading application at /apbrest
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.

INFO: was successfully deployed in 8.179 milliseconds.

Testing the JAX-RS REST API Server with curl

Ok so now l want to test it, using curl is my favorite (in Ubuntu/Debian you can just sudo apt-get install curl), but you can use any tool that understands HTTP requests.

ceefour@annafi:~/project/AbisPulsa/workspace/com.abispulsa.bisnis.service$ curl -v --data-urlencode mobileNumber=08123456 --data-urlencode voucherCode=A5 'http://localhost:8080/apbrest/api/v1/refill'

* About to connect() to localhost port 8080 (#0)
*   Trying ::1... connected
* Connected to localhost (::1) port 8080 (#0)
> POST /apbrest/api/v1/refill HTTP/1.1
> User-Agent: curl/7.21.0 (i686-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/ libidn/1.18
> Host: localhost:8080
> Accept: */*
> Content-Length: 36
> Content-Type: application/x-www-form-urlencoded
< HTTP/1.1 200 OK
< X-Powered-By: Servlet/3.0
< Server: GlassFish Server Open Source Edition 3.0.1
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Date: Thu, 23 Dec 2010 09:34:31 GMT
* Connection #0 to host localhost left intact
* Closing connection #0
MobileNumber=08123456 voucherCode=A5

Alright! So I guess my application works! ;-)

Pretty straightforward, huh?

Using your Own Implementation

As mentioned before, Jersey will create your resource classes.

If you want to control instantiation of your classes, you can create class that implements

After that you configure it in your web.xml like this:

<web-app> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name></param-name> <param-value>MyApplication</param-value> </init-param> </servlet>     ....
I haven't tried it yet, but I think one probable use case is if you want to use Dependency Injection (CDI) in your resource classes.......... ALTHOUGH GlassFish already does this for you (you can use JAX-RS and CDI at the same time), so you probably only use Application for this purpose if the container doesn't support integration between these specs.

Say Goodbye to web.xml

Another, more valid use case and I guess more common if you want to be "pure Java EE 6" is to leave out web.xml altogether:
JAX-RS 1.1 offers a @ApplicationPath annotation applicable to which let you specify the webcontext and remove the need for any web.xml