Introduction:

REST stands for Representational State Transfer and is based on the doctoral dissertation of Roy Fielding
In restful web service every thing considered to be resource. The resource may be text or XML or JSON or HTML or anything.

It Works on HTTP protocols.
      1. GET for reading resources
      2. PUT for creating resources
      3. POST for updating resources
      4. DELETE for deleting resources

We can define the paths to access particular resource by Annotations. Here some importanant annotations are there
      1. @PATH - to define path
      2. @POST - to handle HTTP POST request
      3. @GET - to handle HTTP GET request
      4. @PUT - to handle HTTP PUT request
      5. @DELETE - to handle HTTP DELETE request
      6. @Produces - to define output type
      7. @Consumes - to define input
      8. @PathParam - to get parameter values in post request.
      9. @QueryParam - to get parameter values in get request (in url).
      

Environment setup :

1. required libraries (you can have later versions)
         jersey-client-1.0.3.jar
         jersey-core-1.0.3.jar
         jersey-server-1.0.3.jar
         xstream-1.4.4.jar
2.  download above libraries and add them to build path.
        Download Jersey from the Jersey Homepage jersey        
        Download Xstream from xtream


web.xml

add below XML to web.xml. com.sun.jersey.spi.container.servlet.ServletContainer is a servlet which will handle all URL starts with "/rest/". This servlet must be loaded after starting of web server because this has to hadle all REST requests. com.sample.resources is a package where all service classes exists.


<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.sample.resources</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>


Learn Restful web service with example Case study :

DOWNLOAD PROJECT HERE

GET Method:
1. Create a Class named EmployeeResource (path = employee)
2. Create a method getEmployeeDetails with the following characteristics:
    Path: search
    Method: GET
    Query Parameter 1: version (Data Type = int, Default Value = 1)
    Query Parameter 2: employeeId (Data Type = int)
    Query Paramater 3: employeeName (Data Type = String)
    Produces: XML
3. Validations:
    Either employeeId or employeeName is mandatory. Validate if at least one of
    them is present else throw an exception.If the version is other than 1 
    throw an Exception say “Invalid Version Number”
4. Create an Employee Object (Employee To should contain only 2 attributes 
    employeeId and employeeName) hard code the employeeId and employeeName
5. Convert the Employee Object to XML using XStreams and send the response back.
6. In Case of Exception send the response as 
    <error>
     <errorCode>-1</errorCode>
     <errorMessage>Exception Message</ errorMessage >
    </error>


POST Method:

1. Create a Class named EmployeeResource (path = employee)
2. Create a method maintainEmployeeDetails with the following characteristics:
     a. Path: maintain
     b. Method: POST
     c. Query Parameter 1: version (Data Type = int, Default Value = 1)
     d. FORM Parameter 1: inputData (Data Type =String)
     e. Consumes: XML
     f. Produces: XML
3. Validations:
     a.Check if the inputData is !=NULL and Length >0 else throw an exception.
     b.If the version is other than 1 throw an Exception say 
     “Invalid Version Number”
4. The input Data will be of the Format 
    <employee>
        <employeeId>123456</employeeId>
        <employeeName>Sachin Tendulkar</employeeName>
     </employee>
5. Convert the input XML to Employee Object using XStream
6. Return an XML 
      <success>
          <code>0</code>
          <message>Employee Name parsed successfully</message>
       </success>
   Where Employee Name should be the one sent as Input.
7. In Case of Exception send the response as 
       <error>
          <errorCode>-1</errorCode>
          <errorMessage>Exception Message</ errorMessage >
        </error> 

Build service class :

package com.sample.resources;
import javax.ws.rs.*;

public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
  */
 public String getEmployeeDetails()
                  {
  
                  }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
  */
 public String maintainEmployeeDetails() 
               {
 
  }
}

@Path

We have to use @Path to make our example service web enabled. In below program the path was declared as 
"employee". This means it will handle all type of requests starts with "/employee"
package com.sample.resources;


import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
  */
 public String getEmployeeDetails()
                  {
  
                  }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
  */
 public String maintainEmployeeDetails() 
               {
 
  }
}
in the same way add paths to methods also
package com.sample.resources;
import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
         * it handles http requests starts with "/employee/search" 
         * it handles http GET request
  */
         @GET
  @Path("search")
         public String getEmployeeDetails()
            {
     }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
         * it handles http POST request
         * it handle http requests starts with "/employee/maintain" 
  */
         @POST
         @Path("maintain")
  public String maintainEmployeeDetails() 
             {
      }
}

@GET & @POST :

methods with @GET can handle get requests and methods with @POST can handle post requests.
package com.sample.resources;
import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
         * it handles http requests starts with "/employee/search" 
         * it handles http GET request
  */
         @GET
         @Path("search")
         public String getEmployeeDetails() {
         }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
         * it handles http POST request
         * it handle http requests starts with "/employee/maintain" 
  */
         @POST
         @Path("maintain")
  public String maintainEmployeeDetails()  {
  }
}


@Produces :

@Produces is to define output format of a method,  it may be XML or JSON or text or some other resource.


package com.sample.resources;
import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
               * it handles http requests starts with "/employee/search" 
               * it handles http GET request
  */
        @GET
 @Path("search")
        @Produces("application/xml")
         public String getEmployeeDetails()
                  {
  
                  }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
         * it handles http POST request
         * it handle http requests starts with "/employee/maintain" 
  */
         @POST
         @Path("maintain")
         @Produces("application/xml")
   public String maintainEmployeeDetails() 
               {
 
        }
}

@QueryParam & @FormParam 

These annotations are to get particular parameter value from the input. @QueryParam is to get parameter values in URL (GET request). @FormParam is to get parameter values in the input of POST request (FORM data).

package com.sample.resources;
import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
               * it handles http requests starts with "/employee/search" 
               * it handles http GET request
  */
       @GET
       @Path("search")
       @Produces("application/xml")
       public String getEmployeeDetails(@QueryParam("employeeId") int employeeId,@QueryParam("employeeName") String employeeName)
                  {
  
                  }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
               * it handles http POST request
               * it handle http requests starts with "/employee/maintain" 
  */
       @POST
       @Path("maintain")
       @Produces("application/xml")
 public String maintainEmployeeDetails(@FormParam("inputData") String inputData) 
               {
 
  }
}

Versioning :

One of the biggest maintenance headaches with Web Services in general revolves around maintaining different versions when you have multiple clients accessing your service. Here in REST web applications it is very easy to devide the code into versioning.In the below example if the system unable to find the query parameter then it will take 1 as default value for the parameter "version"

package com.sample.resources;
import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
               * it handles http requests starts with "/employee/search" 
               * it handles http GET request
  */
      @GET
      @Path("search")
      @Produces("application/xml")
       public String getEmployeeDetails(@DefaultValue("1") @QueryParam("version") int version,@QueryParam("employeeId") int employeeId,@QueryParam("employeeName") String employeeName)
                  {
  
                  }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
               * it handles http POST request
               * it handle http requests starts with "/employee/maintain" 
  */
      @POST
      @Path("maintain")
      @Produces("application/xml")
 public String maintainEmployeeDetails(@DefaultValue("1") @QueryParam("version") int version,@FormParam("inputData") String inputData) 
               {
 
  }
}

finally all classes will be like this

Employee pojo class :

This contains employeeId and employeeName as variables

@XStreamAlias :

       this annotation is to define XML tag name Employee class.
           1. If we didnt declare @XStreamAlias then output will be  
                                        <com.Employee>
                          <employeeId></employeeId>
                          <employeeName></employeeName>
                    </com.Employee>

                            2.  If we define @XStreamAlias as "employee" then output will be
                    <employee>
                          <employeeId></employeeId>
                          <employeeName></employeeName>
                    </employee>
           3. In the same way we can define this for methods als

package com.sample.model;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("employee")
public class Employee {
 int employeeId=1;
 String employeeName;

 public int getEmployeeId() {
  return employeeId;
 }

 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }

 public String getEmployeeName() {
  return employeeName;
 }

 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }

}

success pojo class :


package com.sample.model;
import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("employee")
public class Employee {
 int employeeId=1;
 String employeeName;

 public int getEmployeeId() {
  return employeeId;
 }

 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }

 public String getEmployeeName() {
  return employeeName;
 }

 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }

}

error pojo class :

package com.sample.model;
import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("error")
public class ErrorDTO {
 int errorCode;
 String errorMessage;

 public int getErrorCode() {
  return errorCode;
 }

 public void setErrorCode(int errorCode) {
  this.errorCode = errorCode;
 }

 public String getErrorMessage() {
  return errorMessage;
 }

 public void setErrorMessage(String errorMessage) {
  this.errorMessage = errorMessage;
 }

}

XML Generator Class to generate XML :

we can use utility class any where we want. Initailly it will generate XML structure for all classes. We can pass pojo class object to generate XML while running the program. This class will reduce the code and will increase the system performance.
package com.xml;
import com.sample.resources.ErrorDTO;
import com.sample.resources.SuccessDTO;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.sample.resources.Employee;

public final class XMLGenerator {
/*
 * this class is for generating XML 
 */
 
 /*
  * initialization of XStream class 
  */
 private static XStream xstream = new XStream(new DomDriver())
 {{
  processAnnotations(Employee.class);
  processAnnotations(ErrorDTO.class);
  processAnnotations(SuccessDTO.class);
 }};
 
 /*
  * This class is for generating XML from MODEL class
  * @param Object
  * @return String 
  */
 public static String generateXML(Object to) {
  return null == to ? "" : xstream.toXML(to);
 }

 /*
  * Generates the transfer object from the given XML using XStream.
  * 
  * @param String
  * @return transfer object
  */
 public static Object generateTOfromXML(String xml) {
  return xstream.fromXML(xml);
 }
 
 /*
  * this method is for generating error xml
  * @param exception - Exception
  * @return String
  */
 public static String generateErrorXML(Exception exception) {
  
  ErrorDTO errorTO = new ErrorDTO();
  errorTO.setErrorCode(-1);
  errorTO.setErrorMessage(exception.getMessage());
        return generateXML(errorTO);
 }

 /*
  * Sets the error details to the ResponseDTO from the given Exception using XStream.
  * @param String
  * @return String
  */
 public static String generateSuccessXML(String message) {
  SuccessDTO successTO = new SuccessDTO();
  successTO.setCode(0);
  successTO.setMessage(message);
        return generateXML(successTO);
 }
}

Service Class :

package com.sample.resources
import javax.ws.rs.*;

@Path("employee")
 public class EmployeeResource {
/*
 * this class is for get and post employee detals by using
 * REST Full web services
 */
 /*
  * This method is for getting employee details by using employee details
  * and employeeName
  * @return String
               * it handles http requests starts with "/employee/search" 
               * it handles http GET request
  */
               @GET
 @Path("search")
      @Produces("application/xml")
       public String getEmployeeDetails(@DefaultValue("1") @QueryParam("version") int version,@QueryParam("employeeId") int employeeId,@QueryParam("employeeName") String employeeName)
                  {
                        String result = null;
  try {
   switch (version) {
   case 1:
    if (employeeName == null && employeeId == 0) {
     throw new Exception("Invalid parameters");
    } else {
     Employee emp = new Employee();
     emp.setEmployeeId(employeeId);
     emp.setEmployeeName(employeeName);
     result = XMLGenerator.generateXML(emp);
    }
    break;
   default:
    throw new Exception("Invalid version number");
   }
  } catch (Exception e) {
   result = XMLGenerator.generateErrorXML(e);
  }
  return result; 
  
                  }

 /*
  * This method is for maintain employee details by using employee details
  * and employeeName
  * @return String
               * it handles http POST request
               * it handle http requests starts with "/employee/maintain" 
  */
               @POST
               @Path("maintain")
      @Produces("application/xml")
 public String maintainEmployeeDetails(@DefaultValue("1") @QueryParam("version") int version,@FormParam("inputData") String inputData) 
               {
          String result = null;
  try {
   switch (version) {
   case 1:
    if (inputData == null || inputData.length() <1) {
     throw new Exception("Invalid data");
    } else {
     Employee emp = (Employee)XMLGenerator.generateTOfromXML(inputData);
     result=XMLGenerator.generateSuccessXML(emp.getEmployeeName()+" parsed successfully");
    }
    break;
   default:
    throw new Exception("Invalid version number");
   }
  } catch (Exception e) {
   result = XMLGenerator.generateErrorXML(e);
  }
  System.out.println("maintain "+result);
  return result;
  }
}

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 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>sampleREST</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <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.sample.resources</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>
  <servlet>
    <description></description>
    <display-name>NewServlet</display-name>
    <servlet-name>NewServlet</servlet-name>
    <servlet-class>com.sample.resources.NewServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>NewServlet</servlet-name>
    <url-pattern>/NewServlet</url-pattern>
  </servlet-mapping>
</web-app>

Testing 

Here the project name is CaseStudyRest

Input URL -- http://localhost:8080/CaseStudyREST/rest/employee/search?employeeId=2
Output --

<employee> 
   <employeeId>2</employeeId>
</employee>

Input URL -- http://localhost:8080/CaseStudyREST/rest/employee/search?employeeName=2
Output -- 

<employee>
   <employeeId>0</employeeId>  
   <employeeName>2</employeeName>
</employee>


Post Input URL -- http://localhost:8080/CaseStudyREST/rest/employee/maintain
Input Data -- 

<employee>
  <employeeId>5</employeeId> 
  <employeeName>sri</employeeName> 
</employee>

Output -- 


<success>
   <code>0</code>
   <message>sri parsed successfully</message>
</success>


Tester HTML page :


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Tester</title>

</head>
<body>
<a href="http://localhost:8080/CaseStudyREST/rest/employee/search?employeeId=2">http://localhost:8080/CaseStudyREST/rest/employee/search?employeeId=2</a>
<br/>
<a href="http://localhost:8080/CaseStudyREST/rest/employee/search?employeeName=2">http://localhost:8080/CaseStudyREST/rest/employee/search?employeeName=2</a>
<br/>
<form method="post" action="http://localhost:8080/CaseStudyREST/rest/employee/maintain">
<br/><br/><br/>
inputData
<br/>
<br>
<textarea rows="8" cols="60" name="inputData" type="text">
<employee>
  <employeeId>5</employeeId> 
  <employeeName>sri</employeeName> 
</employee>
</textarea><br><br>        
<input type="submit" value="submit"/>
</form>
</body>
</html>




DOWNLOAD PROJECT HERE

0 comments:

Search This Blog

Loading...

Follow by Email

Blogroll

Srinivas Dasari
find me on facebook
follow me on twitter

Popular Posts