Tuesday, April 29, 2014

RESTful Web Services with Java JAX-RS using Jersey and Eclipse - Tutorial

This tutorial shows how to create RESTful web services in Java using Eclipse and Jersey.

REST (Representational State Transfer) is an architectural style based on the HTTP protocol where resources are identified by global IDs (typically using URIs). REST client applications use HTTP methods (GET/ POST/ PUT/ DELETE) to access the service's resources.

RESTful web services are based on HTTP methods and the concept of REST. A RESTful web service should define the base URI for the service, the supported MIME types for the response data (text, XML, JSON,..), and the supported set of operations (GET/ POST/ PUT/ DELETE) of the service.

The Java API for RESTful Web Services (JAX-RS) is an annotation-based API for implementing RESTful web services based on the  HTTP protocol. This is defined in the Java Specification Request (JSR) 311. Jersey is a JAX-RS reference implementation and provides it's own API with additional features and utilities.

JAX-RS also supports the creation of XML and JSON via the Java Architecture for XML Binding (JAXB).


JAX-RS annotations

@Path(/your_resource_path) - sets the path to the base URI + /your_resource_path. The base URI consists of your host, port, any context(project name), and the servlet's url-pattern(eg.; /rest) from the web.xml configuration file.

This tutorial's base URI, for example, is   http://localhost:8080/RESTfulWSDemo/rest
       
@GET - indicates that the annotated method will be invoked by a HTTP GET request   
@PUT - indicates that the annotated method will be invoked by a HTTP PUT request
@POST - indicates that the annotated method will be invoked by a HTTP POST request
@DELETE - indicates that the annotated method will be invoked by a HTTP DELETE request    
@Produces - defines the MIME media type a resource can produce and send back to the client
@Consumes - defines which MIME type is consumed by the method
@PathParam - is used in the method's arguments to set the value of the URI parameters into the methods arguments
@QueryParam - is used in the method's arguments to set the value of the query parameters into the methods arguments.

Query Parameters are the parameters in the http url in the format of a query string where all parameters appear in the end of the url after the '?' symbol and parameters are separated with the '&' symbol
e.g.  http://localhost:8080/RESTfulWS/rest/demo?employeeId1=10&employeeId2=20

Here are the Java JAX-RS and Jersey JAX-RS documentation for a complete listing and description of available annotations and applications.


Development Environment:
1. Eclipse IDE for Java EE Developers 4.3.2  (Kepler)  download
2. Jersey 2.7  download
3. JDK 1.7  download
4. Tomcat 7

This tutorial assumes that you have the Java JDK installed in your machine. You should also have Eclipse installed and configured with  a Tomcat 7 application server.


1. Create a Dynamic Web Project in Eclipse

Set your Eclipse view to Java EE perspective then click on:

File > New > Dynamic Web Project

You will get the shown page below.




For 'Project name':
Enter your project name such as "RESTfulWSDemo". This will be the context root of your application.

For 'Target runtime':
Select 'Apache Tomcat v7.0' or your desired server.

For 'Dynamic web module version':
Select the servlet version you will use. If you are using Java EE 6 or 7, select '3.0'.  If you are using Java EE 5, select '2.5' or lower.

You can see the Servlet mapping with JDK and Tomcat versions from the Tomcat-Servlet-JDK mapping page.

For 'Configuration':
Default Configuration is fine.


Click on 'Next' button

You will get the page shown below.



You don't need to do anything on this page.

Click on 'Next' button

You will get the page shown below.



Check the box for 'Generate web.xml deployment descriptor'.

Click on 'Finish' button.


2. Download Jersey and copy Jersey jars to project's lib folder

Unzip the downloaded Jersey zip file to your local directory.

Copy all the jar files from Jersey's  api, ext and lib folders to your projects  WebContent/WEB-INF/lib  folder.



3. Create your Java class

Right-click on Java Resources/src  folder.

Select New > Class

You will get the page shown below.



Enter your package name and the class name.

Click 'Finish".

Complete your new class with the following code:

package com.ericsoriano.restwebservice;

import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

// @GET annotation registers the method to answer to a HTTP GET request
// @Produces annotation defines which MIME type is delivered by a method annotated with @GET
// @Produces can deliver text, XML, HTML

// The browser requests the HTML MIME type by default

// @Path annotation exposes resource (class and methods) to the client thru base URI + path

// URI = (context root)/(url-pattern in your web.xml's servlet mapping)/(path defined in your @Path annotation)  eg.;   RESTfulWSDemo/rest/demo

// URI parameter values are assigned to variables thru the methods's @Path annotation by enclosing the variables within curly braces "{}" eg.;   @Path("/add/{n1}/{n2}")

// @PathParam annotation is used in the method's signature to set the value of the parameter into the methods arguments
// eg.;  public String add(@PathParam("n1") int n1, @PathParam("n2") int n2)



// This class resource's URI effectively becomes "RESTfulWSDemo/rest/demo" thru the @Path annotation
@Path("/demo")
public class JerseyRESTWSDemo {

   // This method is called if client requests for HTML 
   @GET
   @Produces(MediaType.TEXT_HTML)
   public String serveHTML() {
    return "<html> " + "<title>" + "Jersey REST Demo" + "</title>"
         + "<body><h1>" + "Jersey REST Web Service works!" + "</body></h1>" + "</html> ";
   }

   // This method is called if client requests for TEXT_PLAIN 
   @GET
   @Produces(MediaType.TEXT_PLAIN)
   public String serveText() {
    return "Jersey REST Web Service works!";
   }

   // This method is called if client requests for XML 
   @GET
   @Produces(MediaType.TEXT_XML)
   public String serveXML() {
    return "<?xml version=\"1.0\"?>" + "<message> Jersey REST Web Service works!" + "</message>";
   }
 
   @PUT
   @Path("/{employeeId}")
   @Produces(MediaType.TEXT_PLAIN)
   public String updateInfo(@PathParam("employeeId") String employeeId) {

    // CODE TO UPDATE EMPLOYEE RECORD GOES HERE
        
    return "Employee " + employeeId + " record is updated!";        
   
   }
   
   @GET
   @Path("/add/{n1}/{n2}")
   @Produces(MediaType.TEXT_HTML)
   public String add(@PathParam("n1") int n1, @PathParam("n2") int n2) {
    String output = "The sum of " + n1 + " and " + n2 + " is " + (n1 + n2);
    return "<html> " + "<title>" + "Jersey REST Demo" + "</title>"
         + "<body><h1>" + output + "</body></h1>" + "</html> ";
   }
}





4. Define the Jersey servlet dispatcher in your web.xml

You need to direct all the REST requests to the Jersey container by defining a servlet dispatcher in the application's web.xml file.

Modify the default web.xml created by Eclipse with the code below.

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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>RESTfulWSDemo</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.ericsoriano.restwebservice</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>
</web-app>
 


NOTE: The values for the <servlet-class> and <param-name> are specifications for Jersey 2.0 and higher (Jersey 2.7 as of this writing).

The parameter <param-value>com.ericsoriano.restwebservice</param-value> defines the package Jersey will look at for the web service classes. This property must point to the package of your Java resource classes.

The <url-pattern>/rest/*</url-pattern> defines the base URL pattern to build the URL for your application's rest service classes.


5. Test the RESTful Web Service

Start your RESTful web service application by:

Right-click on project name > Run As > Run on Server

The URL consists of your host, port, context(project name), the servlet's url-pattern(eg.; /rest) from the web.xml configuration file, the /demo @Path annotation on your class file, and any @Path annotation on your methods (eg., /add/10/5)(see second test URL below).    


Test the REST service by typing the following URLs in the browser:

http://localhost:8080/RESTfulWSDemo/rest/demo

Returns this response on the browser:  Jersey REST Web Service works!

See browser screenshot below:





http://localhost:8080/RESTfulWSDemo/rest/demo/add/10/5

Returns this response on the browser:  The sum of 10 and 5 is 15

See browser screenshot below:




No comments:

Post a Comment