About Nitin Kumar

Nitin Kumar works as a Solution Architecture in Wipro Technologies specialize in SOA. He has over twelve years of experience in information technology architecting and developing software systems, focus mainly on JEE solutions.

RESTful Webservices with Jersey

I have discussed my earlier article about architectural consideration<<link>> to become a RESTful system on distributed environment that are usable my system/machines. This article we are going to discuss how to build web services based on REST architecture consideration. 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 and accepted 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 having following major parts:

  • Core Server:  To build RESTful web services based on annotation 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

SoftwareDownload
Java JDK-6http://www.oracle.com/
Eclipse – Indicohttp://www.eclipse.org/
Tomcat Apache -6http://tomcat.apache.org/
H2-Databasehttp://www.h2database.com/

Note: You could download full demo application including H2 and Jersey libraries here<link>

RESTful web service implementation using Jersey

We will build a small application for user management to operate CRUD operations on user. Then, we will create small User table with column username and password and do the CRUD operation using POJO class expose 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

UsersResource.java
@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 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 it help to communicate with server and test the services. The 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 link<>

Resources:

 

Reference: RESTful Webservices with Jersey from our JCG partner Nitin Kumar at the Tech My Talk blog.
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

4 Responses to "RESTful Webservices with Jersey"

  1. Binny says:

    Hi
    I need to create a REST webservice in java which calls various other webservices(REST and SOAP ) both. How can I do that?

  2. Kamal says:

    Hi,
    Thanks for this tutorial, the download link is invisible.
    Thanks

  3. munseym says:

    Would it be possible to do a
    public List testGetUsers()
    method? I know it would be possible to manually parse the XML, but is there any kind of data binding already built in?

  4. Kiran says:

    Hi Nitin Kumar, thanks for providing a valid article on REST Webservice.

Leave a Reply


five + 6 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books