Friday 23 October 2015

How to create a simple maven Restful webservice project using Spring MVC

Here we are going to create a simple restful web service in spring  that returns a model object in JSON format.
 Pre-requisites:-Apache Maven 3.1.1 installed.
                          Eclipse, with jdk7
                          Apache Tomcat 7(To run your service)
                          Postman client for chrome(To test the service)
                          m2e plugin for eclipse
Step 1: Go to your project folder in command prompt and create a maven web project skeleton by using below command

mvn archetype:generate -DgroupId=com.rest.example -DartifactId=RestApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
RestApp project will be created in your project folder. Check the folders.

Step 2: To convert the maven project to eclipse project, please run below command from RestApp folder.This will add eclipse compatibility to your project.

mvn eclipse:eclipse -Dwtpversion=2.0

Step 3: Import the project in eclipse
Open the newly created RestApp project in eclipse by importing the existing project.Inside src/main folder create a java folder along with webapp and resources folders.
Add the java folder also to source in Java build path.
Step 4: Define your rest servlet in web.xml as follows

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>restServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/rest-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>restServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
Step 5:Create your rest-servlet.xml file in WEB-INF folder as follows:


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" 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-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">   
       
              <mvc:annotation-driven/>
                     <bean id="resource" class="com.rest.example.RestControllerExample"></bean>
       
</beans>
Step 6: Create your controller class and model class.
Here we are going to add request mapping to both our controller class and handler method.@RestController is a convenience annotation that does nothing more than adding the @Controller and @ResponseBody annotations.

package com.rest.example;

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.annotation.RestController;
@RestController
@RequestMapping("/rest/data/")
public class RestControllerExample {

@RequestMapping(value="get/msg", method = RequestMethod.GET,headers="Accept=application/json")
public  Message getRestMessage(){
                Message msg=new Message();
                msg.setMsgHeader("Rest Test");
                msg.setContent("Successfully retrived your msg in json format");
                return msg;                
}
}
Model object:-

package com.rest.example;

import java.io.Serializable;

public class Message implements Serializable {
private static final long serialVersionUID = -5319000110698008607L;
private String msgHeader;
private String content;
public String getMsgHeader() {
       return msgHeader;
}
public void setMsgHeader(String msgHeader) {
       this.msgHeader = msgHeader;
}
public String getContent() {
       return content;
}
public void setContent(String content) {
       this.content = content;
}
}
Step 7: Update the pom.xml file with required dependencies.
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.rest.example</groupId>
  <artifactId>RestApp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>RestApp Maven Webapp</name>
  <url>http://maven.apache.org</url>
    <properties>
        <springframework.version>4.0.6.RELEASE</springframework.version>
    </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>    
              <dependency>
                     <groupId>com.fasterxml.jackson.core</groupId>
                     <artifactId>jackson-databind</artifactId>
                     <version>2.2.3</version>
              </dependency>  
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
    
    
  </dependencies>
       <build>
              <finalName>RestApp</finalName>
              <plugins>
                     <plugin>
                           <groupId>org.apache.maven.plugins</groupId>
                           <artifactId>maven-compiler-plugin</artifactId>
                           <version>2.1</version>
                           <configuration>
                                  <source>1.7</source>
                                  <target>1.7</target>
                           </configuration>
                     </plugin>
                       <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
                </configuration>
            </plugin>
              </plugins>
       </build>
</project>

After converting your project to maven project using a m2e plugin, your project structure will be as shown below. Please change the JDK version in project facet to 1.7 if you are facing any compilation errors.

You have probably noticed that we have added jackson2 converter also in pom.xml file.This is for JSON conversion of the object returned from the handler method.Once the response object is returned by the handler method, MappingJackson2HttpMessageConverter kicks in and convert it to JSON response.
That  is why Included below depedncy in pom.xml.
      
 <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.2.3</version>
 </dependency>
This will convert returning objects to json format by default


Step 8: Build and run your restful service
Run mvn install from the command prompt to build the war file. Deploy the war file to tomcat webapp folder. That's it. Start the server and hit the service in postman. You will get the message as shown below.

{
    "msgHeader": "Rest Test",
    "content": "Successfully retrived your msg in json format"


}



Tips:--
Convert  to maven project in eclipse using m2e plugin if required
To fix compiler version change on maven update using m2e plugin, add below in pom.xml

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>2.1</version>
  <configuration>
    <source>1.6</source>
    <target>1.6</target>
  </configuration>
</plugin>


5 comments:

  1. Great job. Thank you for this. There is a problem in that you had defined in your rest-servle.xml file and you used Spring annotations in your RestControllerExample. The app would not deploy because Spring was angry that you had that resource bean defined twice.

    ReplyDelete
  2. Thank you for pointing out this. However it didn't throw error for me while running in tomcat server.

    ReplyDelete
    Replies
    1. Deployed to Weblogic 12c with managed server. Deployment resulted in two Spring exceptions being thrown. when I commented out the defenition in the rest-servlet.xml file it then deployed and ran succesfully.

      Delete
    2. Deployed on Tomcat7: Requires the bean conifugration rest-servlet.xml
      IE: getting response as .json attachment
      Chrome/firefox: display json response on browser

      Any idea?

      Delete
    3. This is just an example of service getting .json data, You can refer this to show data in browser.
      http://simpleapphub.blogspot.in/2016/02/creating-restful-web-service-and.html

      Delete