REST with JAX-RS

REST (REpresentational State Transfer) is an architecture style that describes how to use the Web (HTTP) to access services. JAX-RS (JSR 311) isa Java API to support implementation/access of REST web services using Java. This style was first documented by Ron Fielding.

There will be times we use REST principles without even knowing that we use REST (that is a mouthful). Ever since HTTP came around the largest REST implementation is the web itself.
  • REST prescribes that all services be treated as resources that can be accessed via a URL. Thus the web is REstful.
  • REST also requires the services to be stateless.
  • REST does NOT describe any common data exchange formats. The producer and consumer are free to choose whatever format they can agree on.
  • REST services in many cases are cacheable (though I think in many business cases it is not and thats just fine).
  • REST is commonly used over HTTP (though since it is an architectural style one can use the same principles on any transport).

Used over HTTP the following HTTP methods can be used:
  • GET to retrieve data.
  • DELETE to delete.
  • INSERT to add new data
  • PUT to update data.
Now compare all of this to SOAP based web services where you use a WSDL to publish your interface, we have the SOAP envelope that carries the payload and can optionally provide many services such as transaction,security, addressing, etc (basically the WS-* nightmare). But often we just need to access a simple service without the need for all of the SOAP complexity.. That is where the RESTful architecture style comes in.

On the Java side JAX-RS was introduced to provide a common API to implement/access REST based services in Java. Jersey is the open source reference implementation of REST. Lets get to an example and see how this works. I will implement my usual time service. Call a service to get time of the day in XML, plain text or JSON format.

In Eclipse create a dynamic web project. Here is my layout.
a

Here is the web.xml...
<?xml version="1.0"encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
">java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
   <display-name>jaxrs</display-name>

    <servlet>
       <display-name>jaxrs tryout</display-name>
       <servlet-name>jaxrsservlet</servlet-name>
       <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
       <servlet-name>jaxrsservlet</servlet-name>
       <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

Here is the implementation of the TimeOfTheDayService.  I usethe JAX-WS annotations to configure various JAX-RS attributes.
package com.tryout;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("/timeoftheday")
public class TimeOfTheDayService {

     private static String PATTERN = "MM.dd.yyyy HH:mm:ss";

     @GET
     @Produces("text/plain")
     @Path("/asplaintext/{name}")
      public String getTimeOfTheDay(@PathParam("name") String name) {
           SimpleDateFormat df = new SimpleDateFormat(PATTERN);
           return name + "-" + df.format(Calendar.getInstance().getTime());
      }

     @GET
     @Produces("application/xml")
     @Path("/asxml/{name}/")
      public Time getTimeOfTheDayInXML(@PathParam("name") String name) {
           SimpleDateFormat df = new SimpleDateFormat(PATTERN);
           Time t = new Time();
           t.setName(name);
           t.setTime(df.format(Calendar.getInstance().getTime()));
           return t;
      }

      @GET
     @Produces("application/json")
     @Path("/asjson/{name}/")
      public Time getTimeOfTheDayInJSON(@PathParam("name") String name) {
           SimpleDateFormat df = new SimpleDateFormat(PATTERN);
           Time t = new Time();
           t.setName(name);
           t.setTime(df.format(Calendar.getInstance().getTime()));
           return t;
      }
}

  • @Path("/timeoftheday") - Specifies the URI part for all the services in thisclass.
  • @GET- Used to annotate the read method.
  • @Produces("text/plain")- Marks the method as a producer of plain/text content.
  • @Path("/asjson/{name}/") - Describes the specific method. The optional {name} describes in our case the parameter passed into this service method.
The URL to access the services would be one of:
  • http://localhost:8080/jaxrs/services/timeoftheday/asplaintext/mathew
  • http://localhost:8080/jaxrs/services/timeoftheday/asxml/mathew
  • http://localhost:8080/jaxrs/services/timeoftheday/asjson/mathew
The resource is identified via the URL and so is the parameter name inthis example.

The Time javabean class is:
package com.tryout;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "clock")
public class Time {

      @XmlElement
      private String time;

      @XmlElement
      private String name;

      public void setTime(String time) {
           this.time = time;
      }

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

Deploy the web application. I used the embedded Tomcat instance in Eclipse to run this example. Access one of the URLs mentioned earlier and you will get the response in the appropriate format.

You can also use the jersey client API to access this service...
package com.tryout;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;

public class JSONClient {

      public static void main(String[] args) throws Exception {

           Client c = Client.create();

           //
           WebResource r = c
                       .resource("http://localhost:8080/jaxrs/services/timeoftheday/asplaintext/mathew");
           System.out.println("Plain Text=>> " +r.get(String.class));

           //
           r = c
                       .resource("http://localhost:8080/jaxrs/services/timeoftheday/asxml/mathew");
           System.out.println("XML=>> " + r.get(String.class));

           //
           r = c
                       .resource("http://localhost:8080/jaxrs/services/timeoftheday/asjson/mathew");
           r.accept("application/json");
           System.out.println("JSON=>> " + r.get(String.class));
      }
}

Once you execute this client you should get a response such as:

Plain Text=>>mathew-05.02.2009 08:31:35
XML=>><?xml version="1.0" encoding="UTF-8"standalone="yes"?><clock><time>05.02.200908:31:35</time><name>mathew</name></clock>
JSON=>> {"time":"05.02.2009 08:31:35","name":"mathew"}



Pretty simple ah! Enjoy.

 del.icio.us  Stumbleupon  Technorati  Digg 

 

What did you think of this article?




Trackbacks
  • Trackbacks are closed for this entry.
Comments

Leave a comment

Submitted comments will be subject to moderation before being displayed.

 Enter the above security code (required)

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.