12 May 2015

What is RESTful webservice?

REST stands for REpresentational State Transfer. REST is an architectural style and gaining popularity over SOAP webservices. Below are the REST fundamentals

  • Everything in REST is considered as resource and every resource is identified by URI
  • All resources are handled by GET, POST, PUT, DELETE operations
  • Every request is independent request hence it is stateless.
  • Communication is done via representations e.g. JSON, XML over HTTP protocol.

Objective

The objectives of this blog are

  • understand how to write a RESTful webproject with Jersey framework.
  • Deploy the project in tomcat server
  • Access the webservice

Requeired Software

  • JDK 1.7
  • Eclipse for J2EE
  • Maven 2.2.x or above

Stepts to write code

Below are the steps to write a simple RESTful webservice

  • Create a Dynamic web project with module version 3.0 and java source directory must be src/main/java
  • Convert the project into maven project (right click on project-> Configure -> Convert to Maven project)
  • Create a package under java source (src/main/java): com.ashish.rest.controller
  • Add maven dependancy: Right click on project->properties->Deployment Assembly->Add->Java Build Path Entries->Maven Dependencies Note: Deploy path should be WEB-INF/lib by default The meaning of the below entry (as shown in the image) is that the dependent jars will get packaged into the WEB-INF/lib folder of the deployer

  • Your pom.xml file should be as shown below

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.ashish.rest.controller</groupId>
	<artifactId>RestfulWebservice</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<repositories>
		<repository>
			<id>maven2-repository.java.net</id>
			<name>Java.net Repository for Maven</name>
			<url>http://download.java.net/maven/2/</url>
			<layout>default</layout>
		</repository>
	</repositories>

	<dependencies>
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-server</artifactId>
			<version>1.9</version>
		</dependency>

		<!-- Below two dependencies are added to support JSON response -->
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-json</artifactId>
			<version>1.8</version>
		</dependency>
		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-bundle</artifactId>
			<version>1.18.1</version>
		</dependency>
	</dependencies>

</project>
  • Your web.xml should be as shown below. As per the web.xml file http://server://rest/* request will pass through the controller. Go through the inline comments in the 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>Restful WebApplication</display-name>

	<servlet>
		<servlet-name>jersey-helloWorld-serlvet</servlet-name>
		<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
		<!-- Below init-param is added to for RESTful webservice with Jersey framework -->
		<init-param>
			<param-name>com.sun.jersey.config.property.packages</param-name>
			<param-value>com.ashish.rest.controller</param-value>
		</init-param>

		<!-- Below init-param is added to support JSON response -->
		<init-param>
			<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
			<param-value>true</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>jersey-helloWorld-serlvet</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>
</web-app>

  • Your controller class HelloWorldREST.java should be as shown below. This controller produces string output and json output.

package com.ashish.rest.controller;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.ashish.rest.bean.Employee;

@Path("/hello")
public class HelloWorldREST {
	@GET
	@Path("/{parameter}")
	public Response responseMsg( @PathParam("parameter") String parameter,
			@DefaultValue("Nothing to say") @QueryParam("value") String value) {
		String output = "Hello from: " + parameter + " : " + value;
		return Response.status(200).entity(output).build();
	}
	
	@GET
	@Path("/getEmployee/{empId}")
	@Produces(MediaType.APPLICATION_JSON)
	public Employee getEmployee( @PathParam("empId") int empId,
			@DefaultValue("No Employee Id passed") @QueryParam("value") String value) {

		Employee emp = new Employee();
		emp.setEmpId(empId);
		emp.setName("Ashish Mondal");

		return emp;
	}
	
	@POST
	@Path("/getSalary")
	@Produces(MediaType.APPLICATION_JSON)
	public Employee getSalary( @PathParam("empId") int empId,
			@DefaultValue("No Employee Id passed") @QueryParam("value") String value) {
		System.out.println("getSalary method is called");
		Employee emp = new Employee();
		emp.setEmpId(empId);
		emp.setName("Ashish Mondal");
		emp.setSalary(1000);
		return emp;
	}
}
  • Right click on the project then Run As-> Run on Server
  • 1st request and response from the above controller is shown in the below image
  • 2nd request and response from the above controller is shown in the below image

Note: In the above controller class, getSalary resource can be called by POST and GET methods. The GET method is shown above. I am going to show the POST method below.

  • Note that index.jsp is mentioned as the welcome file in web.xml.
  • Create index.jsp file under WebContent folder and the content should be as shown below


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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>Insert title here</title>
</head>
<body>
	<form method="post" action="rest/hello/getSalary/">
		<div>POST method testing</div>
		<div>
			Emp Id: <input type="text" value="" />
			<button>Go</button>
		</div>
	</form>
</body>
</html>
  • Follow the below steps to test the POST request from webpage

Common issues during project setup

SL NO Issues Solution
1 SEVERE: Servlet /JAXRS-HelloWorld threw load() exception java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer Right click on project->properties->Deployment Assembly->Add->Java Build Path Entries->Maven Dependencies (Note: Deploy path should be WEB-INF/lib by default)
2 com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes. a) com.sun.jersey.config.property.packages doesn’t exist in your web.xml
<servlet>
<servlet-name>jersey-helloWorld-serlvet</servlet-name>
<servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer</br></servlet-class>
<init-param>
<param-name> com.sun.jersey.config.property.packages</param-name>
<param-value>com.ashish.rest.controller</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
b) com.sun.jersey.config.property.packages included a resource that doesn’t include any jersey services. In above case, “com.ashish.rest.controller” doesn’t contains any jersey services.
c) The project’s java source directory must be under src/main/java folder as the project is of type Maven
3 Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class com.ashish.rest.bean.Employee, and Java type class com.ashish.rest.bean.Employee, and MIME media type application/json was not found Add below dependency in pom.xml
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.18.1</version>
</dependency>

Add below entry in web.xml
<init-param><
<param-name><com.sun.jersey.api.json.POJOMappingFeature </param-name><
<param-value><true</param-value><
</init-param><


blog comments powered by Disqus
J2EE,SOAP,RESTful,SVN,PMD,SONAR,JaCoCo,HTTP,API,MAVEN,AngularJS,GitHub,LDAP,AOP,ORM,JMS,MVC,AWS,SQL,PHP,H2DB,JDBC