How to write RESTful web services using spring 3 mvc

Spring is a well-known framework for building Java™ Platform, Enterprise Edition (Java EE) applications, now it supports Representational State Transfer (REST) in its Model-View-Controller (MVC) layer. It's important for RESTful web services to produce multiple representations based on the client requests. In this article, learn how to use Spring APIs and annotations to build RESTful web services that produce popular representations such as ATOM Feed, XML, and JavaScript Object Notation (JSON).

What is REST?
REST is an architectural style that has evolved from existing web technologies to allow client applications to communicate with a server using a simple and familiar approach. The approach is familiar because REST is built on top of the HTTP protocol, a protocol that has formed the backbone of the web for years. REST leverages the existing capabilities of HTTP and uses them to provide an architectural approach for implementing a simple and effective client server model.

RESTFul webservices: A RESTFul webservices are based on the HTTP methods and the concept of REST. A RESTFul webservice typically defines the base URI for the services, the supported MIME-types (XML, Text, JSON, user-defined,..) and the set of operations (POST, GET, PUT, DELETE) which are supported.


REST support in Spring3MVC:
@Controller:-
Use the @Controller annotation to annotate the class that will be the controller in MVC and handle the HTTP request.


@RequestMapping:-
Use the @RequestMapping annotation to annotate the function that should handle certain HTTP methods, URIs, or HTTP headers. This annotation is the key to the Spring REST support. You change the method parameter to handle other HTTP methods.
For example:
@RequestMapping(method=RequestMethod.GET, value="/emps",
headers="Accept=application/xml, application/json")

 

 @PathVariable:-
A path variable in the URI could be injected as a parameter using the @PathVariable annotation.
For example:
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}")
public ModelAndView getEmployee(@PathVariable String id) { … }


Other useful annotations
Use @RequestParam to inject a URL parameter into the method.
Use @RequestHeader to inject a certain HTTP header into the method.
Use @RequestBody to inject an HTTP request body into the method.
Use @ResponseBody to return the content or object as the HTTP response body.
Use HttpEntity to inject into the method automatically if you provide it as a parameter.
Use ResponseEntity to return the HTTP response with your custom status or headers.
For example:
public @ResponseBody Employee getEmployeeById(@RequestParam("name")
String name, @RequestHeader("Accept") String accept, @RequestBody String body) {…}
public ResponseEntity
method(HttpEntity entity) {…}
 

For writing the web application which support RESTfull url then we have follow the steps.
Step 1: Adding the following another jars to the Libs folder.
jaxb-api-2.1.jar
jaxen-1.1.1.jar


Step 2: Update bean configuration file (sdnext-servlet.xml) for view resolvers.
<beans xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

   <mvc:annotation-driven></mvc:annotation-driven>
 
   <context:component-scan base-package="com.dineshonjava.web">
   </context:component-scan>

  <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
     <property name="mediaTypes">
       <map>
   <entry key="html" value="text/html"></entry>
   <entry key="json" value="application/json"></entry>
   <entry key="xml" value="application/xml"></entry>
 </map>
     </property>
     <property name="viewResolvers">
 <list>
  <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView">
            </property>
     <property name="prefix" value="/WEB-INF/views/"></property>
     <property name="suffix" value=".jsp"></property>
   </bean>
 </list>
     </property>
  </bean>
</beans>
Step 3: Add model classes: There are two model classes Employee.java and Employees.java
These classes will be having JAXB annotations, which will be used by marshaller to convert them in appropriate xml or json formats.
Employees.java
package com.dineshonjava.web.model;

import java.util.Collection;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employees")
@XmlAccessorType(XmlAccessType.NONE)
public class Employees {
 @XmlElement(name="employee")
 private Collection<Employee> employees;

 public Collection<Employee> getEmployees() {
  return employees;
 }

 public void setEmployees(Collection<Employee> employees) {
  this.employees = employees;
 }
}
Now write Employee.java
package com.dineshonjava.web.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employees")
@XmlAccessorType(XmlAccessType.NONE)
public class Employee {
 @XmlElement(name="empId")
 private Integer id;
 @XmlElement(name="empName")
 private String name;
 @XmlElement(name="empAge")
 private Integer age;
 @XmlElement(name="empSalary")
 private Long salary;
 @XmlElement(name="empAddress")
 private String address;
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Integer getAge() {
  return age;
 }
 public void setAge(Integer age) {
  this.age = age;
 }
 public Long getSalary() {
  return salary;
 }
 public void setSalary(Long salary) {
  this.salary = salary;
 }
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }
}
Step 4: Write the controller - WebServiceController.java
Our WebServiceController.java will created to have REST specific annotations for path mappings in request parameters mappings. Also, we will specify the header attributes for request and response.
package com.dineshonjava.web.controller;

import java.util.ArrayList;

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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dineshonjava.web.model.Employee;
import com.dineshonjava.web.model.Employees;

/**
 * @author Dinesh Rajput
 *
 */
@Controller
@RequestMapping("/employees")
public class WebServiceController {
 
 @RequestMapping(method = RequestMethod.GET, value="/{id}", headers="Accept=*/*")
 public @ResponseBody Employee getEmployeeById(@PathVariable String id){
  Employee employee = new Employee();
  employee.setId(1);
  employee.setSalary(50000l);
  employee.setName("Dinesh Rajput");
  employee.setAge(26);
  employee.setAddress("Sector 49-Noida");
  return employee;
 }
 
 @RequestMapping(method = RequestMethod.GET,  headers="Accept=*/*")
 public @ResponseBody Employees getEmployees(){
  Employees employees = new Employees();
  
  Employee employee1 = new Employee();
  employee1.setId(2);
  employee1.setSalary(50000l);
  employee1.setName("Dinesh Rajput");
  employee1.setAge(26);
  employee1.setAddress("Sector 49- Noida");
  
  Employee employee2 = new Employee();
  employee2.setId(3);
  employee2.setSalary(20000l);
  employee2.setName("Anamika Rajput");
  employee2.setAge(26);
  employee2.setAddress("Sector 49- Noida");
  employees.setEmployees(new ArrayList<Employee>());
  employees.getEmployees().add(employee1);
  employees.getEmployees().add(employee2);
  return employees;
 }
}
web.xml
<web-app version="2.5" 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_2_5.xsd">

 <servlet>
    <servlet-name>sdnext</servlet-name>
    <servlet-class>
               org.springframework.web.servlet.DispatcherServlet
            </servlet-class>
  <init-param>
            <param-name>contextConfigLocation</param-name><param-value>/WEB-INF/config/sdnext-servlet.xml</param-value></init-param>
        <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>sdnext</servlet-name>
  <url-pattern>*.html</url-pattern>
 </servlet-mapping>

 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
 </welcome-file-list>
</web-app>
Now lets deploy the application on tomcat and hit the URL on any REST client. I am using RESTClient. This is a firefox plugin for testing the RESTful webservices.

Using URL: http://localhost:8080/sdnext/employees/3.html
Now see the following result-
Download Application (Source+Libs)
Spring3WebServiceApp.zip 
 <<Spring Web MVC Framework |index| Spring Logging with Log4J>> 




4 comments:


  1. hi Dinesh,

    I like this tutorial. But i want to get data from database and insert data as xml file. can you provide the example, its very urget.
    My mail id is raju.addanki@gmail.com

    Thanks a lot

    ReplyDelete
    Replies
    1. Hi.. If you want data from database, simply just add dao to the application. If you have any other problem please define or mail me on admin@dineshonjava.com

      So I may some help for you..

      Delete
  2. Hi Dinesh, In this tutorial you explained how to get xml data, what about Json. Please mention what changes should be done, for getting employees data in json.

    ReplyDelete
    Replies
    1. Please look into following.

      http://www.dineshonjava.com/2013/06/restful-web-services-with-jersey-jax-rs.html

      Thanks,
      Dinesh

      Delete