RESTful Webservices with Jersey

I have discussed my earlier article about architectural consideration on  RESTful system for distributed environment. This article we are going to discuss how to build RESTfuk web services with Jersey and Apache Tomcat.

This tutorial explains how to develop RESTful web services in Java with the Tomcat 6, Eclipse and Jersey a JAX-RS (JSR 311) reference implementation.

In a nutshell a RESTful web service is a communication between machines using HTTP on REST principles which have following key points:

  • Each resource represents unique URI to communicate over HTTP protocols
  • Each resource operation supported by HTTP methods (POST, GET, PUT and DELETE)
  • Request and Response supported by JSON, XML and various MIME type such as image, byte stream etc.

JAX-RS

JAX-RS is an annotation-based API for implementing RESTful web services, based on HTTP, in Java. Essentially, classes and methods are annotated with information that enables a runtime to expose them as resources. A runtime that implements JAX-RS mediates between the HTTP protocol and the Java classes, taking into account URIs, requested , content types, and HTTP methods.

Jersey framework implemented JSR-RS(JSR-311) reference APIs. In addition to Jersey various other implementation are available such as Retlet, JBOSS RESTeasy, Apache CXF etc.

Jersey:

Jersey  contains following major parts:

  • Core Server:  To build RESTful web services based on annotation which include key libraries such as : jersey-core.jar, jersey-server.jar, jsr311-api.jar, asm.jar
  • Core Client: The Jersey client API helps you to easily communicate with REST services include libabry ersey-client.jar
  • JAXB support: (Used in the advanced example) jaxb-impl.jar, jaxb-api.jar, activation.jar, stax-api.jar, wstx-asl.jar
  • JSON support: (Used in the advanced example) jersey-json.jar
  • Integration: Jersey also provides libraries that can easily integrate with Spring, Guice, Apache Abdera, and so on.

Getting the tools

Software Download
Java JDK-6 http://www.oracle.com/
Eclipse – Indico http://www.eclipse.org/
Tomcat Apache -6 http://tomcat.apache.org/
H2-Database http://www.h2database.com/

Note: You could download full demo application including H2 database and Jersey libraries here Download Link

RESTful web service implementation using Jersey

We will build a small application for user management to operate CRUD operations on users.

We will create small User table with column username and password and do the CRUD operation using POJO class exposing operation on web services using Jersey annotation.

Following are the design consideration before starting the RESTful web service development.

Application Development folder structure

The directory structure of our application looks as follows:

Reset WS Folder Struc

Following are list of application libraries required:

Reset WS Folder Lib

Application Configuration:

Before starting the development we need to add the Jersey servlet into web.xml to direct the entire request to jersey for resource identification and operation processes (POST, GET, PUT, and DELETE).

After including jersey servlet ,Web.xml will look like as below

<?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>UserManagement</display-name>
 <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>resource.com.users.java</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>Jersey REST Service</servlet-name>
 <url-pattern>/*</url-pattern>
 </servlet-mapping>
</web-app>

Resources

Resources are anything that are addressable and manipulated over the web . Jersey resources are plain java object (POJO) with annotation @Path and will be manipulated by HTTP methods POST, GET,PUT and DELETE. A resource also has sub resources. In the sample application UsersResource for Users java bean is Resources. Users is simple POJO with attributes ‘name’ and ‘password’

<span style="font-family: 'Courier 10 Pitch', Courier, monospace; font-size: 13px;">UsersResource.java</span>
@Path("/users")
public class UsersResource implements IUsersResource{
@Context
UriInfo uriInfo;
@GET
@Produces ("application/xml")
public List<User> getUsersAll() {
List<User> als=null;
try {
als= UserService.getInstance().getUserAll();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return als;
}

@POST
@Consumes ("application/xml")
@Produces ("application/xml")
public User createUser(User user){
URI uri = uriInfo.getAbsolutePathBuilder().path(user.getUserName()).build();
Response res=Response.created(uri).build();
try {
UserService.getInstance().CreateUser(user);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}

@Path("/user/{username}")
@GET
@Produces ("application/xml")

public List<User> getUser(@PathParam("username") String username) {
List<User> asl=null;
try {
asl= UserService.getInstance().getUser(username);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return asl;
}

Below are the explanations of JAX-RS annotation in brief

  • @Path:  Path combined with root path provide URI to identify resource. E.g. in the given example URI will be http://localhost:8080/UserManagement/users
  • @Path(“/user/{username}”): we could also sub path on method to expose sub resources this example URI will be http://localhost:8080/UserManagement/users/user/john
  • @Context: Context use to inject the contextual objects such as Request, Response, UriInfo, ServletContext etc.
  • @PathParam : This annotation is used together with @Path and in conjunction with GET, POST, PUT and DELETE. Other available annotations are @FormParam, @QueryParam etc.
  • @Produces (“application/xml”): Multiple MIME types are supported for responses. In this case, application/xml will be the default MIME type.
  • @Consumes (“application/xml”):  Input Request payload will be send  in xml format.
  • @GET: resources manipulated by one of the GET,POST, PUT and DELET method pass by HTTP header

JAXB – Java POJO XML Binding

Jersey support JAXB which interns to handle POJO to XML conversion and vice versa. To qualify POJO to support XML we have to declare @XmlRootElement annotation as follows:

Don’t forget to add empty constructor as it required during conversion.

@XmlRootElement
public class User {
private String userName;
private String userPasswd;
public User(String userName, String userPasswd) {
this.userName = userName;
this.userPasswd = userPasswd;
}
public User() {
super();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPasswd() {
return userPasswd;
}
public void setUserPasswd(String userPasswd) {
this.userPasswd = userPasswd;
}
}

We will create service classes which perform CRUD operation in User table in H2 database.

UserService.java

public class UserService{
public static UserService userService = new UserService();
public static final String GET_USER="SELECT * FROM USER";
public static final String INSERT_USER="Insert into user ";
public List<User> getUserAll() throws ClassNotFoundException, SQLException {
List<User> ls = new ArrayList();
ls=DataServiceHelper.getInstance().executeQuery(GET_USER);
return ls;
}

public List<User> getUser(String name) throws ClassNotFoundException, SQLException{
String SQL_WHERE_CAS=" where name='"+name+"'";
List<User> als=DataServiceHelper.getInstance().executeQuery(GET_USER+SQL_WHERE_CAS);
return als;
}

public void CreateUser(User user) throws SQLException, ClassNotFoundException {
String SQL_WHERE_CASE=" VALUES('" + user.getUserName() + "','" + user.getUserPasswd() + "')";
DataServiceHelper.getInstance().executeUpdateQuery(INSERT_USER+SQL_WHERE_CASE);
}
public static UserService getInstance() {
return userService;
}
}

Helper classes

We have to create couple of more classes to interact with DB(H2 in our case) and perform CRUD operation.

DaraServiceHelper.java

public class DataServiceHelper {
public static DataServiceHelper dataServiceHelper = null;
private Connection con = null;
DataSource dataSource = null;
InitialContext initialContext = null;
public static final String DB_URL = "jdbc:h2:tcp://localhost/~/test";
public static final String DRIVER_NAME = "org.h2.Driver";
/**

* This method is used to create an object for the given DAO class name.
*/

public Connection getConnection() throws ClassNotFoundException,
SQLException {
Class.forName(DRIVER_NAME);
con = DriverManager.getConnection(DB_URL, "sa", "");
return con;
}

public void closeConnection() throws SQLException {
if (isConnectionOpen()) {
con.close();
con = null;
}
}
public boolean isConnectionOpen() {
return (con != null);
}

public static DataServiceHelper getInstance() {
if (dataServiceHelper == null) {
dataServiceHelper = new DataServiceHelper();
}
return dataServiceHelper;
}

public void executeUpdateQuery(String query) throws SQLException,
ClassNotFoundException {
Connection con = getConnection();
Statement stmt = con.createStatement();
stmt.execute(query);
closeConnection();
}

public List<User> executeQuery(String query) throws ClassNotFoundException,
SQLException {
Connection con = getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
List<User> als = convertPojoList(rs);
closeConnection();
return als;
}

private List<User> convertPojoList(ResultSet rs) throws SQLException {
List<User> asl = new ArrayList<User>();
while (rs.next()) {
User user = new User(rs.getString("name"), rs.getString("password"));
asl.add(user);
}
return asl;
}

public static void main(String[] args) throws ClassNotFoundException,
SQLException {
String query = "Select * from user where name='nitin'";
List<User> als = DataServiceHelper.getInstance().executeQuery(query);
System.out.println("List==>" + als);
}
}

Note: For simplicity I have included all code in one class

Jersey Client Testing

Jersey provide client to test the RESTful web services whic help to communicate with server and test the services. The client library is a generic implementation that can cooperate with any HTTP/HTTPS-based Web service.

public class UserResourceSample {
public static final String USER_URI="http://localhost:8080/UserManagement/users";
public String testGetUsersAll() {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource resource = client.resource(ForumConstant.USER_URI);
ClientResponse response = resource.type(MediaType.APPLICATION_XML).get(
ClientResponse.class);
String en = response.getEntity(String.class);
return en;
}

public String testGetUsers() {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource resource = client.resource(ForumConstant.USER_URI);
ClientResponse response = resource.type(MediaType.APPLICATION_XML).get(
ClientResponse.class);
String en = response.getEntity(String.class);
return en;
}

public User testCreateUser() {
User user = new User("John", "john@");
Client client = Client.create();
WebResource r = client.resource(ForumConstant.USER_URI);
ClientResponse response = r.accept(MediaType.APPLICATION_XML).post(
ClientResponse.class, user);
return user;
}
}

 Run using browser

Run you web application in Eclipse and test the availability of your REST service under: “http://localhost:8080/UserManagement/users&#8221;. You should see the XML representation of your users items

Restful Web Services_testBrow1

For sub resource

Restful Web Services_testBrow2

Note: Before running the application don’t forget to run H2 database and insert the record into User table

 

Conclusion:

This example talks about basic uses of Jersey with Apache tomcat. We will discuss some later on advance JAX-RS uses.  You can also download the full code into below this Download link

References:

http://en.wikipedia.org/wiki/Representational_state_transfer
https://jersey.java.net/

About these ads

One thought on “RESTful Webservices with Jersey

  1. Pingback: Grails – RESTful Webservive using JAX-RS plugin | TechMyTalk

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s