Saturday, September 22, 2012

Spring 3.1 Web Service RESTful part01 - JSON and XML


Environment:
Jdk1.7.07
Maven 3.0.4
Spring Framework version 3.1.1.RELEASE
Spring Source Tools Suits(STS) 3.0

Download Source code here
To open the source code:
File --> Import --> Maven --> Existing Maven Projects


If you are new to Maven, please visit  Maven Tutorial. 
















I am taking the task : development the Web Service REST using Spring Framework 3.1.1.RELEASE. This is the simplest Web Service REST application using URI templates that returns XML and JSON  data.

What is REST?
Representational State Transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation.

Source: http://en.wikipedia.org/wiki/Representational_State_Transfer

The Representational State Transfer (REST) style is an abstraction of the architectural elements within a distributed hypermedia system. REST ignores the details of component implementation and protocol syntax in order to focus on the roles of components, the constraints upon their interaction with other components, and their interpretation of significant data elements. It encompasses the fundamental constraints upon components, connectors, and data that define the basis of the Web architecture, and thus the essence of its behavior as a network-based application.

Source: Architectural Styles and the Design of Network-based Software Architectures, a dissertation of Roy Thomas Fielding,

REST vs SOAP
Unlike SOAP-based web services, there is no "official" standard for RESTful web services. This is because REST is an architecture, unlike SOAP, which is a protocol. Even though REST is not a standard, a RESTful implementation such as the Web can use standards like HTTP, URL, XML, PNG, etc.

Source: http://en.wikipedia.org/wiki/Representational_State_Transfer

What is REST in Spring 3?
For more information, please visit the following links:
- REST in Spring 3: @MVC
- REST in Spring 3: RestTemplate

The Web Service Provider

Our application will provide the information of employee. The Service Provider will produce the XML and JSON  data.

Domain Layer

We have domain object Employee.

Employee.java
package org.sample.mvc.domain;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="employee")
public class Employee implements Serializable{
 
 public Employee(){}
 
 //Constructor for making sample data
 public Employee(Integer id
   , String firstName
   , String lastName
   , String userName
   , String email
   , String phone
   , String image){
  this.id   = id;
  this.firstName = firstName;
  this.lastName = lastName;
  this.userName = userName;
  this.email  = email;
  this.phone  = phone;
  this.image  = image;
 }

 private static final long serialVersionUID = 1L;


 private Integer id; 

 
 private String firstName;
 
 
 private String lastName;
 
 
 private String userName;
 
 
 private String email;
 
 
 private String phone;
 
  
 private String image;
 
 
 
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public String getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
 public String getPhone() {
  return phone;
 }
 public void setPhone(String phone) {
  this.phone = phone;
 }
 public String getImage() {
  return image;
 }
 public void setImage(String image) {
  this.image = image; 
 }
} 

Employee is a simple POJO, and we've annotated the class name with @XmlRootElement(name="employee"). Its purpose is to help JAXB (the one responsible for marshalling/unmarshalling to XML) determine the root of our POJO.

The Controller Layer
The controller layer is the most important section of the provider service because here's where we define the RESTful services available to our clients.
EmployeeController .java
package org.sample.mvc.restful;

import org.sample.mvc.domain.Employee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class EmployeeController {
 private Logger logger = LoggerFactory.getLogger(getClass());

 /**
  * Sample URL: http://localhost:8080/app0140/restful/employeeid/1 
  */
 @RequestMapping("/employeeid/{id}")
 public @ResponseBody Employee getEmployeeById(@PathVariable Integer id) {
  logger.trace("Serving resource for id : " + id);
  return new Employee(id,"White","Rose","whiterose","whiterose1@gmail.com","123456789","img_whiterose");
 }
}

Put the URL http://localhost:8080/app0140/restful/employeeid/1 into the browser,  the result will be as following.

Configuration

Configuring REST support in Spring is almost the same Spring MVC. That's because REST in Spring are additional "features to Spring MVC itself" (See Rest in Spring 3: @MVC blog).

Here are all the XML in the project
log4j.xml





 
 
  
  
   
  
 

 
  
 

 
 
  
  
 


servlet-context.xml



 

 
 
 

 


root-context.xml


 
 
  

web.xml



 JSON and XML RESTful web service example part01
 
 
 
  contextConfigLocation
  /WEB-INF/spring/root-context.xml
 
 
 
 
  org.springframework.web.context.ContextLoaderListener
 

 
 
  appServlet
  org.springframework.web.servlet.DispatcherServlet
  
   contextConfigLocation
   /WEB-INF/spring/appServlet/servlet-context.xml
  
  1
 

 
  appServlet
  /restful/*
 


pom.xml


 4.0.0
 org.sample
 app0140
 Spring 3.1 Web Service RESTful part01
 war
 1.0.0
 
  3.1.1.RELEASE
  1.6.0
 
 
  
  
   org.springframework
   spring-webmvc
   ${org.springframework-version}
  

  
  
   org.slf4j
   slf4j-api
   ${org.slf4j-version}
  
  
   org.slf4j
   slf4j-log4j12
   ${org.slf4j-version}
   runtime
  
   
  
  
   org.codehaus.jackson
   jackson-mapper-asl
   1.9.5
   jar
   compile
  
 
 
 
  
   
    org.apache.maven.plugins
    maven-compiler-plugin
    2.3.2
    
     1.7
     1.7
     true
    
   
  
 


Verify the result of Spring 3.1 Web Service RESTful.
When we test Spring 3.1 Web Service RESTful with the browser, we always get the result with xml data.
Now, we use the tool restclient-ui-3.0-jar-with-dependencies  to get the result with json data.




1) Choose HTTP Method GET , input the URL http://localhost:8080/app0140/restful/employeeid/1


 2)Input Header key Accept and value  application/json ---> Click >> button


3) This is the result with json data



More explain about HTTP Method and Headers.
With the Web Service RESTful application above, beside service for HTTP GET Method, it also services for HTTP POST Method, HTTP PUT Method, HTTP DELETE Method.

1) HTTP POST Method



 2)HTTP PUT Method


3) HTTP DELETE Method


 To narrow down the user's scope, for example: user can use the GET Method and POST Method only, we need add some configuration in the EmployeeController

 
@RequestMapping(value="/employeeid/{id}", method={RequestMethod.GET, RequestMethod.POST})
 public @ResponseBody Employee getEmployeeById(@PathVariable Integer id) {
  logger.trace("Serving resource for id : " + id);
  return new Employee(id,"White","Rose","whiterose","whiterose1@gmail.com","123456789","img_whiterose");
 }

1)Allow Method GET and Method POST.



 

2) Not allow Method PUT and Method DELETE.




To narrow down the user's scope, for example: user can use the with xml data only, we need add some configuration in the EmployeeController

@RequestMapping(value="/employeeid/{id}", headers="Accept=application/xml")
 public @ResponseBody Employee getEmployeeById(@PathVariable Integer id) {
  logger.trace("Serving resource for id : " + id);
  return new Employee(id,"White","Rose","whiterose","whiterose1@gmail.com","123456789","img_whiterose");
 }

1)Accept xml data.


2) Not Accept json data


Reference

Spring 3: REST Web Service Provider and Client Tutorial (Part 1)

Combining JSON and XML in RESTful web services with Spring MVC