Wednesday, July 9, 2014

Simple REST Service using spring MVC

How to write a simple REST full service using spring MVC

Step 1:   

Create the following files in resources folder:

Web.xml
 

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    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-app_2_4.xsd">

    <display-name>SampleRESTServlet</display-name>
    <description>Example Spring MVC App for SampleRESTServlet</description>
    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>SampleRESTServlet</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:log4j.xml</param-value>
    </context-param>

    <!-- The definition of the Root Spring Container shared by all Servlets
        and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--
        HTTP Method Conversion to support HTML's lack of support for the HTTP verbs DELETE and PUT.
        If using spring's form tags designate the action as delete or put. If using standard forms or request arguments,
        create an hidden input or request param named _method with the value of DELETE or PUT.
   
    -->
    <filter>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <servlet-name>SampleRESTServlet</servlet-name>
    </filter-mapping>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>SampleRESTServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-web.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SampleRESTServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file></welcome-file>
    </welcome-file-list>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>


 

 
ApplicationContext.xml (which contains all your context services or hibernate settings)

Incase if you have used  hibernate features , include those files in applicationcontext.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"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/util
                        http://www.springframework.org/schema/util/spring-util-3.1.xsd
                        http://www.springframework.org/schema/jee
                        http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd">
                       
   <!-- base package which has all the annotation classes to be scanned -->
    <context:component-scan base-package="org.vels.samples.rest" />

    <import resource="applicationContext-resources.xml" />
    <import resource="applicationContext-services.xml" />
    <import resource="applicationContext-hibernate.xml" />

</beans>

applicationContext-resources.xml :

Enabling the transaction manager for all your hibernate transactions and specifying the application datasource whic got created and configured  in your WAS server.

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        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">

    <tx:annotation-driven />
    <tx:jta-transaction-manager/>


    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    <jdbc:embedded-database id="dataSource"/>
</beans>


applicationContext-hibernate.xml

 Specify all your hibernate settings/properties

<?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:p="http://www.springframework.org/schema/p"
    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">
   
  
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="org.vels.samples.rest.domain"/>     
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            </props>
        </property>
  </bean>

</beans>

applicationContext-services.xml


If you have some componets that would be used in your application , you can specify that.

<?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">


</beans>


Step 2:  

ApplicationContext-web.xml


This will enable the REST feature in spring MVC

<?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:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    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
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

    <context:component-scan base-package="org.vels.samples.rest.web" />

    <mvc:annotation-driven />
   
</beans>

Step 3:

Write the controller class which would have all the REST functionalities.


package org.vels.samples.rest.web;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
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 org.springframework.web.bind.support.SessionStatus;

@Controller
public class OrderController {
    private static Log logger = LogFactory.getLog(OrderController.class);
    private ShoppingService shoppingService; // your service class which has all the buss logic to 
                                                                     invoke dao layer
   
    @Autowired
    public OrderController(ShoppingService shoppingService) { /// you can inject your service class
        this.shoppingService = shoppingService;
    }
   
    @RequestMapping("/orders")
    public @ResponseBody Map<String, ? extends Object> orders(){
        logger.debug("Loading all Orders");

        
         // you can write code to invoke the database vis sevice and dao layer

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orders", orders);

        return map;
    }



    @RequestMapping(value="/order/{id}", method=RequestMethod.GET)
    public String order(@PathVariable Long id, Model model) {



     
       // you can write code to invoke the database vis sevice and dao layer
      
        return "success";
    }



}


 Step 4:  Deploy into server by creating WAR/EAR.


Step 5 :
 Invoke the REST service  from your browser in following way to test the REST service

URL :

http://localhost:9080/rest-services/orders

output :

{"orders":[{"itemSize":0,"totalCost":0.0,"orderId":123,"description":"test
 order","createDate":1404849946247,"modifiedDate":1404849946247,"shoppingItems":[]}]}



Incase if you want full source code i can send it.....



No comments:

Post a Comment