Saturday, July 2, 2011

Hosting a RESTful web services interface using JAX-RS (Java)

RESTful web services are built to work best on the Web. Representational State Transfer (REST) is an architectural style that specifies constraints, such as the uniform interface, that if applied to web services induce desirable properties, such as performance, scalability, and modifiability, that enable services to work best on the Web. In the REST architectural style, data and functionality are considered resources and are accessed using Uniform Resource Identifiers (URIs), typically links on the Web.
The following principles encourage RESTful applications to be simple, lightweight, and fast:
·         Resource identification through URI: A RESTful web service exposes a set of resources that identify the targets of the interaction with its clients. Resources are identified by URIs, which provide a global addressing space for resource and service discovery.

·         Uniform interface: Resources are manipulated using a fixed set of four create, read, update, delete operations: PUT, GET, POST, and DELETE. PUT creates a new resource, which can be then deleted by using DELETE. GET retrieves the current state of a resource in some representation. POST transfers a new state onto a resource.

·         Self-descriptive messages: Resources are decoupled from their representation so that their content can be accessed in a variety of formats, such as HTML, XML, plain text, PDF, JPEG, JSON, and others. Metadata about the resource is available and used, for example, to control caching, detect transmission errors, negotiate the appropriate representation format, and perform authentication or access control.

·         Stateful interactions through hyperlinks: Every interaction with a resource is stateless; that is, request messages are self-contained. Stateful interactions are based on the concept of explicit state transfer. Several techniques exist to exchange state, such as URI rewriting, cookies, and hidden form fields. State can be embedded in response messages to point to valid future states of the interaction.

Creating a RESTful Root Resource Class

Root resource classes are POJOs that are either annotated with @Path or have at least one method annotated with @Path or a request method designator, such as @GET, @PUT, @POST, or @DELETE. Resource methods are methods of a resource class annotated with a request method designator. This section explains how to use JAX-RS to annotate Java classes to create RESTful web services.

Developing RESTful Web Services with JAX-RS

JAX-RS is a Java programming language API designed to make it easy to develop applications that use the REST architecture.
The JAX-RS API uses Java programming language annotations to simplify the development of RESTful web services. Developers decorate Java programming language class files with JAX-RS annotations to define resources and the actions that can be performed on those resources. JAX-RS annotations are runtime annotations; therefore, runtime reflection will generate the helper classes and artifacts for the resource. A Java EE application archive containing JAX-RS resource classes will have the resources configured, the helper classes and artifacts generated, and the resource exposed to clients by deploying the archive to a Java EE server.

Java API:

Jars required:
asm-3.1.jar
jackson-core-asl-1.5.5.jar
jackson-jaxrs-1.5.5.jar
jackson-mapper-asl-1.5.5.jar
jackson-xc-1.5.5.jar
jaxb-impl-2.1.10.jar
jersey-client-1.5.jar
jersey-core-1.5.jar
jersey-json-1.5.jar
jersey-server-1.5.jar
jettison-1.3.jar
jsr311-api-1.1.1.jar

The below java code accepts a JSON message (or JSONObject) and sends back a JSON message. Hence, @Produces and @Consumes message type is JSON.

@Path signifies the URI to post the request into the interface.
@POST signifies that it will accept a post request

Java Code:

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 org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

//Path Reference to access this interface
@Path("/sampleRequest")
public class SampleRestInterface {

      @POST
      @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
      @Consumes("application/json")
      public JSONObject requestCardPairing(JSONObject object) {
            JSONObject response = null;
            JSONObject responseHeader = null;

            try {
                  // Displaying all the received parameters in console
                  System.out.println("firstname :" + object.getString("firstname"));
                  System.out.println("lastname :" + object.getString("lastname"));
                  System.out.println("event :" + object.getString("company"));
                  System.out.println("can :" + object.getString("grade"));
                  System.out.println("vcn :" + object.getString("post"));

                  System.out.println("Constructing the Response");

                  response = new JSONObject();
                  responseHeader = new JSONObject();

                  // Constructing the response - Start
                  responseHeader.put("errorCode", "0");
                  responseHeader.put("errorText", "Employee Creation Successful");

                  response.put("EmployeeHeader", responseHeader);
                  // Constructing the response - End
            } catch (JSONException e) {
                  System.out.println(" JSONException occured in post method "
                              + e.getMessage());
                  e.printStackTrace();
            } catch (Exception e) {
                  System.out.println(" Exception occured in post method "
                              + e.getMessage());
                  e.printStackTrace();
            }
            System.out.println("Returning the Response");
            return response;
      }
}



 
<?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 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      id="WebApp_ID" version="2.5">
      <display-name>Sample Rest Interface</display-name>
      <servlet>
            <servlet-name>Sample Rest Interface</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>test</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
            <servlet-name>Sample Rest Interface</servlet-name>
            <url-pattern>/*</url-pattern>
      </servlet-mapping>
</web-app>





Web.xml file for deployment descriptor

Build.xml [Ant Script] file to prepare war file


 
<!DOCTYPE project>

<project name="Sample Rest Interface" default="buildAll" basedir=".">

      <property name="project-name" value="BuildCPS" />

      <property name="build" value="build" />
      <property name="dist" value="dist" />
      <property name="src" value="src" />
      <property name="build.samplerest.classes" value="build/samplerest/classes" />
     
      <target name="buildAll" depends="sample_rest_war" />

      <target name="sample_rest_compile">
            <echo message="Compiling java files" />
            <javac srcdir="src" destdir="${build.samplerest.classes}" deprecation="true" failonerror="true" debug="true">
                  <classpath refid="refer_classpath" />
            </javac>
      </target>

      <target name="sample_rest_war" depends="prepare,sample_rest_compile">
            <echo message="Creating war distribution" />
            <mkdir dir="dist/samplerest" />
            <mkdir dir="dist/samplerest/WEB-INF" />
            <mkdir dir="dist/samplerest/WEB-INF/lib" />
            <mkdir dir="dist/samplerest/WEB-INF/classes" />
            <copy todir="dist/samplerest/WEB-INF/classes" overwrite="true">
                  <fileset dir="${build.samplerest.classes}" />
            </copy>
            <copy todir="dist/samplerest/WEB-INF/lib" overwrite="true">
                  <fileset dir="lib" />
            </copy>
            <copy todir="dist/samplerest/WEB-INF" overwrite="true">
                  <fileset file="web.xml" />
            </copy>
           
            <jar jarfile="dist/samplerest.war">
                  <fileset dir="dist/samplerest" />
            </jar>
           
            <delete dir="dist/samplerest" />
      </target>

      <target name="prepare" depends="clean">
            <mkdir dir="${build}" />
            <mkdir dir="${build.samplerest.classes}" />
            <mkdir dir="${dist}" />
      </target>

      <target name="clean">
            <delete dir="${build}"/>
            <delete dir="${dist}"/>
      </target>
     
      <path id="refer_classpath">
            <fileset dir="lib">
                  <include name="**/*.jar" />
            </fileset>
      </path>
</project>



IDE/Server where the project is being built: Eclipse/Weblogic

Post Deployment checks:

IT will give http 405 error, as we have implemented post method and browser generally triggers a GET request.

Hope this be helpful to you!


 

No comments:

Total Pageviews