Spring MVC 4.0 RESTFul Web Service JSON Response with @ResponseBody




Article Recognitions*

  • A mention about this article in official spring blog here.
  • Big Link in Dzone

This tutorial is a continuation of my previous tutorial titled Spring MVC 4.0 RESTFul Web Service Simple Example. I explained the basics of how Spring MVC can be used to build RESTFul Web Services with a simple example that returns greeting message in the form of plain text. Let us extend that example to see how to use Spring MVC REST functionality to return json response from server.


As I mentioned in my previous article, we can eliminate the usage of ViewResolver as Spring provides an out of the box functionality wrapped inside @ResponseBody annotation. @ResponseBody converts the return value to one of the predefined set of MIME types (ex. XML, JSON etc) and writes it directly to http response. This annotation uses Jackson JSON library to convert Java object to javascript objects internally, therefore we must add Jackson JSON jar file to the classpath of our application in order for it to return response in JSON format .

In this tutorial, I am going to explain with an example, on how to build Spring RESTFul Web Service that would return user information in JSON format from an underlying MySql table. This example only covers the select operation using GET http method. For other operations such as creating, updating and deleting, you can also refer to this spring article.



Lets get started with our sample application,

1. Download latest version of jackson json library from here,

     -- jackson-annotations-x.x.x.jar
     -- jackson-core-x.x.x.jar
     -- jackson-databind-x.x.x.jar

2. Create a dynamic web project in eclipse and add the above downloaded jar files along with spring jar files to your applications WEN-INF\lib folder.


3. Now edit web.xml file under WebContent folder to notify the application container about the spring configuration file. Add below code before </web-app>

<servlet>
 <servlet-name>rest</servlet-name>
 <servlet-class>
  org.springframework.web.servlet.DispatcherServlet
 </servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
 <servlet-name>rest</servlet-name>
 <url-pattern>/*</url-pattern>
</servlet-mapping>


Note that in the above code,we have named Spring Dispatcher servlet class as "rest" and the url pattern is given as "/*" which means any uri with the root of this web application will call DispatcherServlet. So what's next? DispatcherServlet will look for configuration files following this naming convention - [servlet-name]-servlet.xml. In this example, I have named dispatcher servlet class as "rest" and hence it will look for file named 'rest-servlet.xml'.

3. Create a file under WEB-INF folder and name it as "rest-servlet.xml". Add below spring configuration code to it,


<?xml version="1.0" encoding="UTF-8"?>
<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"
 xmlns:p="http://www.springframework.org/schema/p"
 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">
 <context:component-scan base-package="com.programmingfree.springservice.controller" />
 <mvc:annotation-driven />
  </beans>

I have already explained component-scan element and mvc:annotation-driven element in my previous article, so I am not going to repeat it here again.

4. Let us now proceed with writing the actual business logic. Our aim is to serve data from database in json format based on the request received. Create a table in MySql server using the following query,

CREATE TABLE tblUser(
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `lastname` varchar(45) DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`userid`)
)

Insert some dummy values into it.

5. Create a java class and name it as "User.java". This is a model class that represents the data in the database.

package com.programmingfree.springservice.domain;

public class User {

 private int userid;
 private String firstName;
 private String lastName; 
 private String email;
 
 public int getUserid() {
  return userid;
 }
 public void setUserid(int userid) {
  this.userid = userid;
 }
 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 getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
 @Override
 public String toString() {
  return "User [userid=" + userid + ", firstName=" + firstName
    + ", lastName=" + lastName + ", email="
    + email + "]";
 }
  
  
}

6. Create a utility class to handle connections to database. The connection string properties are kept in a configuration file called "db.properties" in the src folder.

package com.programmingfree.springservice.utility;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;


public class DBUtility {
 private static Connection connection = null;

    public static Connection getConnection() {
        if (connection != null)
            return connection;
        else {
            try {
             Properties prop = new Properties();
                InputStream inputStream = DBUtility.class.getClassLoader().getResourceAsStream("/config.properties");
                prop.load(inputStream);
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("user");
                String password = prop.getProperty("password");
                Class.forName(driver);
                connection = DriverManager.getConnection(url, user, password);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return connection;
        }

    }

}

Properties configuration file should have contents such as this,

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/databasename
user=username
password=xxxxxx


7. Create a service class that performs data access operations to get data from database,

package com.programmingfree.springservice.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import com.programmingfree.springservice.domain.User;
import com.programmingfree.springservice.utility.DBUtility;


public class UserService {
 
 private Connection connection;

 public UserService() {
  connection = DBUtility.getConnection();
 }
  

 public List<User> getAllUsers() {
  List<User> users = new ArrayList<User>();
  try {
   Statement statement = connection.createStatement();
   ResultSet rs = statement.executeQuery("select * from tblUser limit 15");
   while (rs.next()) {
    User user = new User();
    user.setUserid(rs.getInt("userid"));
    user.setFirstName(rs.getString("firstname"));
    user.setLastName(rs.getString("lastname"));    
    user.setEmail(rs.getString("email"));
    users.add(user);
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }

  return users;
 }
 
 public User getUserById(int userId) {
  User user = new User();
  try {
   PreparedStatement preparedStatement = connection.
     prepareStatement("select * from tblUser where userid=?");
   preparedStatement.setInt(1, userId);
   ResultSet rs = preparedStatement.executeQuery();
   
   if (rs.next()) {
    user.setUserid(rs.getInt("userid"));
    user.setFirstName(rs.getString("firstname"));
    user.setLastName(rs.getString("lastname"));
    
    user.setEmail(rs.getString("email"));
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return user;
 }

}

8. Finally let us now write Spring Controller Class that maps the incoming request to appropriate methods and returns response in json format. We are going to use @RestController annotation which has @Controller and @Responsebody annotated within itself.

package com.programmingfree.springservice.controller;

import java.util.List;

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.RestController;

import com.programmingfree.springservice.dao.UserService;
import com.programmingfree.springservice.domain.User;


@RestController
@RequestMapping("/service/user/")
public class SpringServiceController {
 
 UserService userService=new UserService();
           
 @RequestMapping(value = "/{id}", method = RequestMethod.GET,headers="Accept=application/json")
 public User getUser(@PathVariable int id) {
  User user=userService.getUserById(id);
  return user;
 }
 
 @RequestMapping(method = RequestMethod.GET,headers="Accept=application/json")
 public List<User> getAllUsers() {
  List<User> users=userService.getAllUsers();
  return users;
 }
 
 
}

So at the end the structure of src folder will look like this,



If you take a look at the SpringServiceController class we have mapped all requests to the relative path '/service/user' using @RequestMapping annotation. There are two methods, one that returns all user data(getAllUsers()) does not take any additional request parameter and the other that returns data specific to a user id takes userid as parameter (/service/user/userid).

Run the application in Tomcat Server and launch http://localhost:8080/ApplicationName/service/user/ from browser. You must see all user information listed in json format such as this,



To get specific user information, userid needs to be appended to the request url such as this, 'http://localhost:8080/Applicationname/service/user/2'



We have created a spring rest service that returns json repsonse from server based on the HTTP request. In my next article I will write on how to consume this service from a Spring application using RestTemplate.

Keep yourself subscribed via email or social networking sites to get notified whenever a new article is published.



Subscribe to GET LATEST ARTICLES!


Related

Trending 4138230127186774746

Post a Comment

  1. i love the way you represent things..... !! thanks a lot !! :) :)

    ReplyDelete
  2. This tutorial is great !! thank you for the sharing... :)

    ReplyDelete
  3. It would be even more helpful if u have explained the code of reading JSON object and JSON array on the client side. Thanks

    ReplyDelete
    Replies
    1. Hi Deepak,

      I had already explained how to issue we service queries and display data in JSP's using RestTemplate here,

      http://www.programming-free.com/2014/04/spring-mvc-consuming-restful-web-services.html

      If you are looking for a pure AJAX way of issuing web service requests and parsing json in front end, that is yet to come here in ProgrammingFree. Stay subscribed to get notified.

      Thanks,
      Priya

      Delete
  4. What would be the implementation of the method to insert, modify and remove a record using @ RequestMapping post, put and delete? Thanks,

    ReplyDelete
    Replies
    1. Hi,

      It is very similar except for the fact that you have to change the RequestMethod value to POST, PUT or DELETE. Have a look at the final part of this article to understand this,

      http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch18s02.html

      Thanks,
      Priya

      Delete
  5. hello, I am new to web services.i want to fetch data from web service into angular-js controller and display to the client side page. my web service and controller as bellow

    $scope.onProfilechange = function (SetProfile){

    alert(SetProfile);


    $http.post('/app/api/user/Settingprofile',{profileName:SetProfile}).
    success(function (data)
    {

    /*alert(data);*/

    $scope.myForm.user.from= data.setFrom;


    }).
    error(function(data, status){
    alert("Error "+ status);
    });


    };
    web service:

    package services;

    import javax.inject.Named;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;

    @Named
    @Path("/api/user")
    public class SettingProfileController {

    @POST
    @Path("/Settingprofile")
    @Produces("application/json")
    @Consumes("application/json")
    public Setting doSettingProfile(SettingProfile settingProfile)

    {

    /*String profileName =settingProfile.getProfileName();*/

    Setting setting = new Setting();
    setting.setFrom("govind.rasal@sungard.com");
    setting.setTo("govindpbn@gmail.com");
    setting.setCc("rgovind90@gmail.com");
    setting.setBcc("welcome to safal");
    setting.setSubject("sungard");
    setting.setHeader("testing tool");
    setting.setAutoemail("true");
    setting.setFailedtestcases("true");
    setting.setTempfile("true");
    setting.setBrowser("");
    /*setting.setFailueraction();
    setting.setHighlight();
    setting.setBlink();*/
    setting.setBrowsertype("google chrome");
    setting.setBrowserlanguage("English");
    setting.setMaxinstance("5");
    setting.setLanguage("English");
    setting.setSelectlogin("info");
    setting.setParameterlist("true");
    setting.setProducttype("STA,infinity");
    setting.setTechnologytype("Java Access bridge");
    /*setting.setReport("excel");*/
    /*setting.setActionfailuer();

    /*return (profileName + from);*/
    return setting;

    }

    }

    ReplyDelete
  6. Hi,
    Thank you for this tutorial, I downloaded your code, when I run it, the console show :

    WARNING: No mapping found for HTTP request with URI [/SpringServiceJsonSample/] in DispatcherServlet with name 'rest'

    and when I go to the url :
    http://localhost:8080/SpringServiceJsonSample/service/user/

    a dilog box popup, it says :
    Do you want to save this file, or find a program online to open it? Name: user.json

    Please I am new here,your help is appreciated

    ReplyDelete
    Replies
    1. Did you hit this URL in IE? By default IE treats incoming files of types other than HTML, text or images as things it cannot handle and therefore hands over to the user to ask them what to do with it. Try hitting the same url in any other modern browser (Firefox or Chrome).

      However, you can also try this workaround for IE,

      http://www.codeproject.com/Tips/216175/View-JSON-in-Internet-Explorer

      Thanks,
      Priya

      Delete
  7. hi, this page is really helpful,

    can u provide me the addUser() method in controller class, im getting difficulty to get it, can u provide it .

    ReplyDelete
  8. Thanks for such a nice post.
    One question, How can we introduce a validation layer for REST services here. The layer is supposed to do the data validation before processing the request like standard web services.

    Thanks

    ReplyDelete
  9. hiii
    when i am trying to access above code using ajax call
    i am getting error No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed acces

    ReplyDelete
  10. In a situation where I am posting JSON representation of an entity whose member fields are references to other entities, e.g an Account with a member field of type Customer, How do I format the JSON where I am posting a new Account for an existing Customer?

    ReplyDelete
  11. am getting 404 error. how to rectify? please reply asap.

    ReplyDelete
    Replies
    1. you should eliminate / sign at the end of @RequestMapping("/service/user/"). And it will become like that
      @RequestMapping("/service/user)

      Delete
  12. am getting an error "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers." while loading the url "http://localhost:8080/SpringServices/service/user/1" which for a particulat user.

    please help me to solve this.

    ReplyDelete
    Replies
    1. solved it..its a mistake from my side....
      Thanks nice tutorial..

      Delete
    2. Good that you got it working!

      Delete
  13. Can you please explain how JSON is parsed by Jackson In this example
    what does this piece of code do? "@RequestMapping(headers="Accept=application/json")"

    ReplyDelete
  14. Hello,
    I am getting this exception. Please help me.
    HTTP Status 500 - Servlet.init() for servlet rest threw exception
    Thanks in advance.

    ReplyDelete
  15. Hi i got output for above program
    now i want to use name in the place of "/{id}" the example shown below...

    @RequestMapping(value = "/{id}", method = RequestMethod.GET,headers="Accept=application/json")
    public User getUser(@PathVariable int id) {
    User user=userShop.getUserById(id);
    return user;
    can any one help..

    ReplyDelete
  16. how to connect multiple tables using above example...?

    ReplyDelete
  17. HTTP Status 406 -

    type Status report

    message

    description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
    Apache Tomcat/8.0.30


    ////////

    please help me to solve this problem.

    ReplyDelete
    Replies
    1. i have solved my problem. thank you for this good tutorial..

      Delete

emo-but-icon

SUBSCRIBE


item