Saturday 13 April 2013

REST web-service With CRUD Operations Using Spring and Hibernate

REST web-service example with Create, Retrieve, Update and Delete Operations

Here I am mentioning the annotations used with this project as below

@XmlRootElement : -

When a top level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document.
Usage: - The @XmlRootElement annotation can be used with the following program elements:
  • a top level class
  • an enum type
@Controller:-

This annotation indicates that a particular class serves as a controller. The basic purpose of the @Controller annotation is to act as a stereotype for the annotated class, indicating its role. The dispatcher will scan such annotated classes for mapped methods, detecting @RequestMapping annotations.  This is easily achieved by using the spring-context schema.
@Controller annotation in spring provides a feature of auto detection. To enable auto detection of such annotated controllers, we have to add “component-scan” in spring-context and needs to provide the base-package name or controller class package name.
 <context:component-scan base-package="gaurav.example.spring.controller" />

@RequestMapping :-

This annotation is used to map a web-request to a specific class or method in controller which will handle the corresponding request.  We can apply this annotation for both at class level and method level. In class level we need to map the URL of the web-request (http request) and in method level we can map url or we can also map HTTP request methods. Example:-
@RequestMapping(method = RequestMethod.GET, value = "/getEmployees")


@RequestBody :-

This annotation indicates that a method parameter should be bound to the value of the HTTP request body.
@RequestMapping(method = RequestMethod.POST, value = "/saveEmployee")
      public ModelAndView saveEmployeeInDB(@RequestBody String body) {

            Source source = new StreamSource(new StringReader(body));
            EmpBean e = (EmpBean) jaxb2Mashaller.unmarshal(source);
            System.out.println("the val from addEmployee-" + e.toString());
            employeeDS.saveEmployee(e);
            return new ModelAndView(XML_VIEW_NAME, "emp", e);
      }

Here we are converting the request body to the method argument by using an HttpMessageConverter. HttpMessageConverter is responsible for converting from the HTTP request message to an object and converting from an object to the HTTP response body. DispatcherServlet supports annotation based processing using the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter.
In Spring 3.0 the AnnotationMethodHandlerAdapter is extended to support the @RequestBody and has the following HttpMessageConverters registered by default:
·         ByteArrayHttpMessageConverter converts byte arrays.
·         StringHttpMessageConverter converts strings.
·         FormHttpMessageConverter converts form data to/from a MultiValueMap<String, String>.
·         SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
·         MarshallingHttpMessageConverter converts to/from an object using the org.springframework.oxm package.
Note: - Reference from springsource.org

@PathVariable: -

In Spring MVC we can use the @PathVariable annotation on a method argument to bind it to the value of a URI template variable.
@RequestMapping(method = RequestMethod.DELETE, value = "/removeEmployee/{id}")
      public ModelAndView removeEmployeeFromDB(@PathVariable String id) {

            employeeDS.removeEmployee(Long.parseLong(id));
            List<EmpBean> employees = employeeDS.getAllAfterDelete();
            EmpListBean list = new EmpListBean(employees);
            return new ModelAndView(XML_VIEW_NAME, "empBeanList", list);
      }
This will extract the part of the URL represented by {id}, and bind it to the id method parameter, e.g. taken as a string.
Java 5 enumeration of HTTP request methods. Intended for use with the RequestMapping.method () attribute of the RequestMapping  annotation.  Note that, by default, DispatcherServlet supports GET, HEAD, POST, PUT and DELETE only.

contextConfigLocation: -(Note :- This is a parameter(init/context), not annotation)

This init-param is required by DispatcherServlet. Using this parameter, we can change the name of Spring’s web context file and also we can change its(Spring’s web context file) location.
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
                                                /WEB-INF/restWebServiceWithCRUDOperations-context.xml
                                </param-value>
  </context-param>

Note: - contextConfigLocation parameter will call setContextConfigLocation method on DispatcherServlet and overrides default spring context config file. It is also possible to add multiple locations separated by any number of commas and space.
<init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-bean.xml, /WEB-INF/spring-bean-ds.xml, /WEB-INF/spring-bean-service.xml</param-value>
</init-param>



STEPS
1) Create a dynamic web project in Eclipse.

2) Name it as RestWebServiceWithCRUDUsingSpring.

3) Create a package in src folder and name as gaurav.example.spring.bean.

4) Place EmpBean.java and EmpListBean.java file in the above created package.

 (Below is the source code available for EmpBean.java and EmpListBean.java)

5) Create a package in src folder with name gaurav.example.spring.controller.

6) Place the EmpController.java file source code.

(Below is the source code available for EmpController.java)

7) Create a package in src folder with name gaurav.example.spring.ds.

8) Place the source code of EmpDS.java in that package.

(Below is the source code available for EmpDS.java)

9) In the src folder create a file with name EmpBean.hbm.xml and place the source code of
    EmpBean.hbm.xml. Below is the source code available for EmpBean.hbm.xml.

10) Similarly, in the src folder create a file with name hibernate.cfg.xml and place the
      source code of hibernate.cfg.xml. Below is the source code available for
      hibernate.cfg.xml

11) In the WEB-INF directory, create a folder named with jsp and create a file with name
      employeeView.jsp in that folder, and place the source code for employeeView.jsp as it is
      available below.

12) In the WEB-INF directory, create the tags directory and place the c.tld file, this is the
      JSTL core library file, here I am also placing the source code with this post.

13) Similarly, In the WEB-INF directory, create two xml files with name
      restWebServiceWithCRUDOperations-context.xml and
      restWebServiceWithCRUDOperations-servlet.xml. Place the codes for both the files,
      source code is available below

14) Change the code of web.xml file, which is available in WEB-INF directory of this
      project. Take the web-xml file source code from below.

15) Right click on the project, select Run As and then click Run on Server, configure
      Tomcat, here I am using Tomcat 7.0 version.




After click on next below screen will appear and click on Finish will start the Tomcat server and deploy this application.



Source Files:-

EmpBean.java 

package gaurav.example.spring.bean;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "emp")
public class EmpBean {

    private long id;
    private String name;
    private String email;

    public EmpBean() {
    }

    public EmpBean(long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

EmpListBean.java

package gaurav.example.spring.bean;

import java.util.List;

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

@XmlRootElement(name = "allEmployee")
public class EmpListBean {

    private int count;
    private List<EmpBean> empBeanList;

    public EmpListBean() {
    }

    public EmpListBean(List<EmpBean> employees) {
        this.empBeanList = employees;
        this.count = employees.size();
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @XmlElement(name = "emp")
    public List<EmpBean> getEmpBeanList() {
        return empBeanList;
    }

    public void setEmpBeanList(List<EmpBean> empBeanList) {
        this.empBeanList = empBeanList;
    }

}

EmpController.java

package gaurav.example.spring.controller;

import gaurav.example.spring.bean.EmpBean;
import gaurav.example.spring.bean.EmpListBean;
import gaurav.example.spring.ds.EmpDS;

import java.io.StringReader;
import java.util.List;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class EmpController {

    private EmpDS employeeDS;

    public void setEmployeeDS(EmpDS ds) {
        this.employeeDS = ds;
    }

    private Jaxb2Marshaller jaxb2Mashaller;

    public void setJaxb2Mashaller(Jaxb2Marshaller jaxb2Mashaller) {
        this.jaxb2Mashaller = jaxb2Mashaller;
    }

    private static final String XML_VIEW_NAME = "employeeView";

    @RequestMapping(method = RequestMethod.GET, value = "/getEmployees")
    public ModelAndView retrieveEmployeesFromDB() {

        List<EmpBean> employees = employeeDS.retrieveEmployee();
        EmpListBean list = new EmpListBean(employees);
        return new ModelAndView(XML_VIEW_NAME, "empBeanList", list);

    }

    @RequestMapping(method = RequestMethod.POST, value = "/saveEmployee")
    public ModelAndView saveEmployeeInDB(@RequestBody String body) {

        Source source = new StreamSource(new StringReader(body));
        EmpBean e = (EmpBean) jaxb2Mashaller.unmarshal(source);
        System.out.println("the val from addEmployee-" + e.toString());
        employeeDS.saveEmployee(e);
        return new ModelAndView(XML_VIEW_NAME, "emp", e);
    }

    @RequestMapping(method = RequestMethod.PUT, value = "/updateEmployee/{id}")
    public ModelAndView updateEmployeeInDB(@RequestBody String body) {

        Source source = new StreamSource(new StringReader(body));
        EmpBean e = (EmpBean) jaxb2Mashaller.unmarshal(source);
        employeeDS.updateEmployee(e);
        return new ModelAndView(XML_VIEW_NAME, "emp", e);
    }

    @RequestMapping(method = RequestMethod.DELETE, value = "/removeEmployee/{id}")
    public ModelAndView removeEmployeeFromDB(@PathVariable String id) {

        employeeDS.removeEmployee(Long.parseLong(id));
        List<EmpBean> employees = employeeDS.getAllAfterDelete();
        EmpListBean list = new EmpListBean(employees);
        return new ModelAndView(XML_VIEW_NAME, "empBeanList", list);
    }

}

EmpDS.java

package gaurav.example.spring.ds;

import gaurav.example.spring.bean.EmpBean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class EmpDS {

    private static Map<Long, EmpBean> allEmployees;

    static {
        allEmployees = new HashMap<Long, EmpBean>();

    }

    /*
     * This Method will be used to retrieve the employee Details after deleting
     * the data from the DB
     */
    @SuppressWarnings("unchecked")
    public List<EmpBean> getAllAfterDelete() {

        List<EmpBean> employees = retrieveEmployee();
        for (Iterator<EmpBean> it = allEmployees.values().iterator(); it
                .hasNext();) {
            EmpBean e = it.next();
            employees.add(e);
        }
        return employees;
    }

    /* This Method will be used to retrieve the employee Details from the DB */
    @SuppressWarnings("rawtypes")
    public List retrieveEmployee() {

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        List emps = new ArrayList();
        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        try {

            emps = session.createQuery("from EmpBean").list();

            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return emps;
    }

    // This Method will be used to save the employee Details in the DB
    public String saveEmployee(EmpBean emp) {
        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        System.out.println("emp---" + emp.getName());
        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        String saveStatus = null;
        try {
            session.save(emp);
            tx.commit();
            saveStatus = "Saved Successfully";
        } catch (HibernateException e) {
            tx.rollback();
            saveStatus = "Error While Saving the Employee Bean ";
            e.printStackTrace();
        } finally {
            session.close();
        }
        return saveStatus;
    }

    // This Method will be used to save the employee Details in the DB
    public String updateEmployee(EmpBean emp) {
        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        System.out.println("emp---" + emp.getName());
        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        String saveStatus = null;
        try {
            session.saveOrUpdate(emp);
            tx.commit();
            saveStatus = "updated Successfully";
        } catch (HibernateException e) {
            tx.rollback();
            saveStatus = "Error While updating the Employee Bean ";
            e.printStackTrace();
        } finally {
            session.close();
        }
        return saveStatus;
    }

    // This Method will be used to remove the employee Details from the DB
    public String removeEmployee(Long empId) {

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();

        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        String removeStatus = null;
        try {
            EmpBean empBean = (EmpBean) session.get(EmpBean.class, empId);
            session.delete(empBean);
            tx.commit();
            removeStatus = "Employee Removed Successfully";
        } catch (HibernateException e) {
            tx.rollback();
            removeStatus = "Error While deleting empId";
            e.printStackTrace();
        } finally {
            session.close();
        }
        return removeStatus;
    }

}
EmpBean.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="gaurav.example.spring.bean.EmpBean" table="Employee">
        <id name="id" column="id" type="long">
            <generator class="assigned" />
        </id>

        <property name="name" column="name" />
        <property name="email" column="email" />

    </class>
</hibernate-mapping>


hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="hibernate.connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.pool_size">1</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <mapping resource="EmpBean.hbm.xml" />
    </session-factory>
</hibernate-configuration>


employeeView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Employees</title>
</head>
<body>
<table border=1>
    <thead><tr>
        <th>ID</th>
        <th>Name</th>
        <th>Email</th>
    </tr></thead>
    <c:forEach var="employee" items="${empBeanList.empBeanList}">
    <tr>
        <td>${employee.id}</td>
        <td>${employee.name}</td>
        <td>${employee.email}</td>
    </tr>
    </c:forEach>
</table>
</body>
</html>


restWebServiceWithCRUDOperations-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context">

    <bean id="employeeDS" class="gaurav.example.spring.ds.EmpDS" />
</beans>


restWebServiceWithCRUDOperations-servlet.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    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">

    <context:component-scan base-package="gaurav.example.spring.controller" />
    <!-- To enable @RequestMapping process on type level and method level -->
    <bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>gaurav.example.spring.bean.EmpBean</value>
                <value>gaurav.example.spring.bean.EmpListBean</value>
            </list>
        </property>
    </bean>

    <bean id="empMarshallingViewId"
        class="org.springframework.web.servlet.view.xml.MarshallingView">
        <constructor-arg ref="jaxbMarshaller" />
    </bean>

    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="application/xml" />
                <entry key="html" value="text/html" />
            </map>
        </property>
        <property name="viewResolvers">
            <list>
                <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
                <bean id="viewResolver"
                    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
                    <property name="viewClass"
                        value="org.springframework.web.servlet.view.JstlView" />
                    <property name="prefix" value="/WEB-INF/jsp/" />
                    <property name="suffix" value=".jsp" />
                </bean>
            </list>
        </property>
    </bean>
    <bean id="empController" class="gaurav.example.spring.controller.EmpController">
        <property name="employeeDS" ref="employeeDS" />
        <property name="jaxb2Mashaller" ref="jaxbMarshaller" />
    </bean>
</beans>

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" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
    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>RestWebServiceWithCRUDUsingSpring</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/restWebServiceWithCRUDOperations-context.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>restWebServiceWithCRUDOperations</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>restWebServiceWithCRUDOperations</servlet-name>
        <url-pattern>/service/*</url-pattern>
    </servlet-mapping>
    <jsp-config>
        <taglib>
            <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
            <taglib-location>/WEB-INF/tags/c.tld</taglib-location>
        </taglib>
    </jsp-config>
</web-app>

Project Structure is as below:-


The Project Library files which I am using with this project is shown below:-


The URL's which we can use for application testing purpose is as below:-
These URL's we can fire through RESTClient which is a plugin for Mozile web-browser.

1) GET - http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/getEmployees

2) POST - http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/saveEmployee
XML Data Format
<emp>
<id>11</id>
<name>Aaditya</name>
<email>Aadi@yahoo.com</email>
</emp>


3) PUT - http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/updateEmployee/9
XML Data Format
<emp>
<id>9</id>
<name>Deepak</name>
<email>Deepak@orkut.com</email>
</emp>

4) DELETE - http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/removeEmployee/9

When we will try to use GET method at the very first time and fire the URL http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/getEmployees, then it will not show any records in the table as the table is newly created, so there is no records available.
Note:- My Tomcat Server is running on 7075 port number.

Source Code for c.tld file(We can get this on internet):-

c.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
   
  <description>JSTL 1.1 core library</description>
  <display-name>JSTL core</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>c</short-name>
  <uri>http://java.sun.com/jsp/jstl/core</uri>

  <validator>
    <description>
        Provides core validation features for JSTL tags.
    </description>
    <validator-class>
        org.apache.taglibs.standard.tlv.JstlCoreTLV
    </validator-class>
  </validator>

  <tag>
    <description>
        Catches any Throwable that occurs in its body and optionally
        exposes it.
    </description>
    <name>catch</name>
    <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
Name of the exported scoped variable for the
exception thrown from a nested action. The type of the
scoped variable is the type of the exception thrown.
        </description>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
    Simple conditional tag that establishes a context for
    mutually exclusive conditional operations, marked by
    &lt;when&gt; and &lt;otherwise&gt;
    </description>
    <name>choose</name>
    <tag-class>org.apache.taglibs.standard.tag.common.core.ChooseTag</tag-class>
    <body-content>JSP</body-content>
  </tag>

  <tag>
    <description>
    Simple conditional tag, which evalutes its body if the
    supplied condition is true and optionally exposes a Boolean
    scripting variable representing the evaluation of this condition
    </description>
    <name>if</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
The test condition that determines whether or
not the body content should be processed.
        </description>
        <name>test</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    <type>boolean</type>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
resulting value of the test condition. The type
of the scoped variable is Boolean.       
        </description>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Scope for var.
        </description>
        <name>scope</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
        Retrieves an absolute or relative URL and exposes its contents
        to either the page, a String in 'var', or a Reader in 'varReader'.
    </description>
    <name>import</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.ImportTag</tag-class>
    <tei-class>org.apache.taglibs.standard.tei.ImportTEI</tei-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
The URL of the resource to import.
        </description>
        <name>url</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
resource's content. The type of the scoped
variable is String.
        </description>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Scope for var.
        </description>
        <name>scope</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
resource's content. The type of the scoped
variable is Reader.
        </description>
        <name>varReader</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the context when accessing a relative
URL resource that belongs to a foreign
context.
        </description>
        <name>context</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Character encoding of the content at the input
resource.
        </description>
        <name>charEncoding</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
    The basic iteration tag, accepting many different
        collection types and supporting subsetting and other
        functionality
    </description>
    <name>forEach</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.ForEachTag</tag-class>
    <tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
Collection of items to iterate over.
        </description>
    <name>items</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>java.lang.Object</type>
    </attribute>
    <attribute>
        <description>
If items specified:
Iteration begins at the item located at the
specified index. First item of the collection has
index 0.
If items not specified:
Iteration begins with index set at the value
specified.
        </description>
    <name>begin</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>int</type>
    </attribute>
    <attribute>
        <description>
If items specified:
Iteration ends at the item located at the
specified index (inclusive).
If items not specified:
Iteration ends when index reaches the value
specified.
        </description>
    <name>end</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>int</type>
    </attribute>
    <attribute>
        <description>
Iteration will only process every step items of
the collection, starting with the first one.
        </description>
    <name>step</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>int</type>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
current item of the iteration. This scoped
variable has nested visibility. Its type depends
on the object of the underlying collection.
        </description>
    <name>var</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
status of the iteration. Object exported is of type
javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested
visibility.
        </description>
    <name>varStatus</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
    Iterates over tokens, separated by the supplied delimeters
    </description>
    <name>forTokens</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.ForTokensTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
String of tokens to iterate over.
        </description>
    <name>items</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    <type>java.lang.String</type>
    </attribute>
    <attribute>
        <description>
The set of delimiters (the characters that
separate the tokens in the string).
        </description>
    <name>delims</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    <type>java.lang.String</type>
    </attribute>
    <attribute>
        <description>
Iteration begins at the token located at the
specified index. First token has index 0.
        </description>
    <name>begin</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>int</type>
    </attribute>
    <attribute>
        <description>
Iteration ends at the token located at the
specified index (inclusive).
        </description>
    <name>end</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>int</type>
    </attribute>
    <attribute>
        <description>
Iteration will only process every step tokens
of the string, starting with the first one.
        </description>
    <name>step</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    <type>int</type>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
current item of the iteration. This scoped
variable has nested visibility.
        </description>
    <name>var</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the exported scoped variable for the
status of the iteration. Object exported is of
type
javax.servlet.jsp.jstl.core.LoopTag
Status. This scoped variable has nested
visibility.
        </description>
    <name>varStatus</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
        Like &lt;%= ... &gt;, but for expressions.
    </description>
    <name>out</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.OutTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
Expression to be evaluated.
        </description>
        <name>value</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Default value if the resulting value is null.
        </description>
        <name>default</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Determines whether characters &lt;,&gt;,&amp;,'," in the
resulting string should be converted to their
corresponding character entity codes. Default value is
true.
        </description>
        <name>escapeXml</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>


  <tag>
    <description>
        Subtag of &lt;choose&gt; that follows &lt;when&gt; tags
        and runs only if all of the prior conditions evaluated to
        'false'
    </description>
    <name>otherwise</name>
    <tag-class>org.apache.taglibs.standard.tag.common.core.OtherwiseTag</tag-class>
    <body-content>JSP</body-content>
  </tag>

  <tag>
    <description>
        Adds a parameter to a containing 'import' tag's URL.
    </description>
    <name>param</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.ParamTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
Name of the query string parameter.
        </description>
        <name>name</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Value of the parameter.
        </description>
        <name>value</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
        Redirects to a new URL.
    </description>
    <name>redirect</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.RedirectTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
The URL of the resource to redirect to.
        </description>
        <name>url</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the context when redirecting to a relative URL
resource that belongs to a foreign context.
        </description>
        <name>context</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
        Removes a scoped variable (from a particular scope, if specified).
    </description>
    <name>remove</name>
    <tag-class>org.apache.taglibs.standard.tag.common.core.RemoveTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <description>
Name of the scoped variable to be removed.
        </description>
        <name>var</name>
        <required>true</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Scope for var.
        </description>
        <name>scope</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

 <tag>
    <description>
        Sets the result of an expression evaluation in a 'scope'
    </description>
    <name>set</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.SetTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
Name of the exported scoped variable to hold the value
specified in the action. The type of the scoped variable is
whatever type the value expression evaluates to.
        </description>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Expression to be evaluated.
        </description>
        <name>value</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Target object whose property will be set. Must evaluate to
a JavaBeans object with setter property property, or to a
java.util.Map object.
        </description>
        <name>target</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the property to be set in the target object.
        </description>
        <name>property</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Scope for var.
        </description>
        <name>scope</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
        Creates a URL with optional query parameters.
    </description>
    <name>url</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.UrlTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
Name of the exported scoped variable for the
processed url. The type of the scoped variable is
String.
        </description>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Scope for var.
        </description>
        <name>scope</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
URL to be processed.
        </description>
        <name>value</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>
Name of the context when specifying a relative URL
resource that belongs to a foreign context.
        </description>
        <name>context</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <description>
    Subtag of &lt;choose&gt; that includes its body if its
    condition evalutes to 'true'
    </description>
    <name>when</name>
    <tag-class>org.apache.taglibs.standard.tag.rt.core.WhenTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <description>
The test condition that determines whether or not the
body content should be processed.
        </description>
        <name>test</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    <type>boolean</type>
    </attribute>
  </tag>

</taglib>
Now after deploying the application, we can open mozila browser and from Tools menu we can select Add-ons and install RESTClient or any other REST web-service client.

I have installed the RESTClient and now I am starting the testing of application using the RESTClient.

Results:-

 1) When Method is GET and URL is http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/getEmployees. As the table is newly created so it is not having the records.


     Here in the below screenshot we can see the Response Headers, when the method is GET.



2) When Method is POST and URL is http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/saveEmployee.


Similarly, I have inserted one more record using the method POST as below. 


Now after inserting the records i am again hitting the GET method with the corresponding getEmployees URL.


Here in the above screen shot we can see that two records are successfully inserted in the table.

Now we can check the PUT and DELETE methods.

3) When the request method is PUT and URL is http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/updateEmployee/id, here id is empid - an integer number which record we want to update using PUT method


In the above screen-shot we can see that I have updated the empid-5, earlier whose name was Kumar Gaurav and email was kumargaurav@gmail.com, Now the name is updated with the name Aryan and email is updated with the Aryan@orkut.com. Below we can see the updated record as i again fired the GET method.


 4) When the request method is DELETE and URL is http://localhost:7075/RestWebServiceWithCRUDUsingSpring/service/removeEmployee/id, Here id is empid, which record i want to delete from the table. For deleting a record from table i passed the id as 5. now in the below screen shot we can see that the record is delete from the table.


     Testing of this application is completed, every request is getting the proper response as we can see in 
     the screen shot.

21 comments:

  1. Very interesting. Could you give me some suggestion in how develop a client to this REST webservice using JSP? Thanks very much!

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Hi,
      For developing the JSP, you need to define the action attribute and commandName attribute of form tag in the JSP, and you also need to use the @ResponseBody annotations in the controller for the method which you want to access through the JSP, for the persist methods commandName is the model attribute and for get method returning pojo list is the commandName, and this list you can iterate using JSTL forEach loop.

      Delete
  2. Hey Gaurav, I am not able to access the POST, PUT and DELETE methods. It gives me an error saying "Request method 'GET' not supported"

    ReplyDelete
  3. Never Mind!!! its working like a charm. Thanks for the great post.

    ReplyDelete
  4. Which IDE have you used?

    ReplyDelete
  5. Hello Kumar, sample application is awesome, I followed all steps in your post but when I ran a restclient application to test GET, POST, PUT, ...
    I'm getting "HTTP/1.1 500 Internal Server Error".
    When I looked at stack trace, it shows
    org.hibernate.hql.internal.ast.QuerySyntaxException: EmpBean is not mapped [from EmpBean]

    SEVERE: Servlet.service() for servlet [restWebServiceWithCRUDOperations] in context with path [/RestWebServiceWithCRUDUsingSpring] threw exception [Could not resolve view with name 'employeeView' in servlet with name 'restWebServiceWithCRUDOperations'] with root cause
    javax.servlet.ServletException: Could not resolve view with name 'employeeView' in servlet with name 'restWebServiceWithCRUDOperations'
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1190)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)





    Do you have any idea?
    Your feedback will be very appreciated.

    Thanks

    ReplyDelete
  6. Hi thank you for giving such a good tutorial but I tried your example and I have written all codes and configured all files according to your instruction but when I executed this application it has thrown exception :-------

    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

    please sort out this problem I have already checked but I think there is no any mistake.

    ReplyDelete
  7. This problem you are facing due to jar file mismatch, please check the version of spring jars

    ReplyDelete
  8. This comment has been removed by a blog administrator.

    ReplyDelete
  9. nice jersey tutorial visit

    http://www.javaproficiency.com/2015/03/jersey-tutorial-for-beginners.html

    ReplyDelete
  10. Hi thank you for giving such a good tutorial but I tried your example and I have written all codes and configured all files according to your instruction but when I executed this application it has thrown exception :-------HTTP Status 404 - /RestWebServiceWithCRUDUsingSpring/service1/getEmployees what can do for solve?

    ReplyDelete
  11. Hey Gaurav,What is the role of EmpListBean file in this project..thanks for this tutorial.it's good and working

    ReplyDelete
  12. Great Tutorial

    ReplyDelete
  13. But where is index file i.e. home page of application
    because for running on the server tomcat is unable to search the index.html which is defined on web.xml....
    so please reply as soon as possible

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. How to get response in terms of JSON.

    ReplyDelete
  16. Hi Gaurav,

    Could you help with example using angularJS + Spring Rest + Hibernate + MYSQL

    ReplyDelete