Spring REST Hello World Example – JSON and XML responses

As we already know Spring Core, Spring MVC and REST Web service. Now its our turn to learn Spring with REST Web services as a single entity. In this Spring REST Example we will be learning how to produce JSON and XML response by creating a simple REST service using Spring 4.

Folder Structure :

  1. Create a Dynamic Web Project SpringRESTTutorial and create a package for our src files com.javainterviewpoint
  2. Place the required jar files under WEB-INF/Lib 

    spring-aop-4.2.4.RELEASE.jar
    spring-beans-4.2.4.RELEASE.jar
    spring-context-4.2.4.RELEASE.jar
    spring-core-4.2.4.RELEASE.jar
    spring-expression-4.2.4.RELEASE.jar
    spring-web-4.2.4.RELEASE.jar
    spring-webmvc-4.2.4.RELEASE.jar
    commons-logging-1.2.jar
    jackson-annotations-2.4.6.jar
    jackson-core-2.4.6.jar
    jackson-databind-2.4.6.jar

  3. Create the Java classes Student.java and StudentService.java under  com.javainterviewpoint folder.
  4. Place the web.xml  and SpringConfig-servlet.xml under the WEB-INF directory

Student.java

package com.javainterviewpoint;

import java.io.Serializable;

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

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Student implements Serializable 
{
    @XmlElement
    private String name;
    @XmlElement
    private String age;
    public Student()
    {
        super();
    }
    public Student(String name, String age)
    {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getAge()
    {
        return age;
    }
    public void setAge(String age)
    {
        this.age = age;
    }
    @Override
    public String toString()
    {
        return "Student [name=" + name + ", age=" + age + "]";
    }
}

Our Student class act as the model here

  • we have annotated our class with @XmlRootElement, which indicates the root tag is our class.
  • @XmlAccessorType(XmlAccessType.FIELD) is set to FIELD, so JAXB implementations will create bindings for fields and annotated properties
  • @XmlElement – Maps a JavaBean property to the XML element

StudentService.java

package com.javainterviewpoint;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/student")
public class StudentService
{
    @RequestMapping(value="/studentJson", method=RequestMethod.GET,
            produces="application/json")
    public Student getStudentJSON()
    {
        Student st = new Student();
        st.setName("JavaInterviewPoint");
        st.setAge("111");
        
        return st;
    }
    
    @RequestMapping(value="/studentXml", method=RequestMethod.GET,
            produces="application/xml")
    public Student getStudentXml()
    {
        Student st = new Student();
        st.setName("JavaInterviewPoint");
        st.setAge("999");
        
        return st;
    }
}
  • We have annotated our “StudentService” class with @RestController, In Spring 4 @RestController annotation is introduced it is a combination of @Controller + @ResponseBody. So when using @RestController, you do not need to use @ResponseBody it is optional now
  • getStudentJson() Method :
    • Jackson2JsonMessageConverter is automatically registered in the Spring Context if the Jackson Dependency libraries are found. As we have added jackson-core.jar, jackson-annotations.jar, jackson-databind.jar and hence Jackson2JsonMessageConverter will be registered automatically.
    • @RequestMapping annotation on top of getStudentJson() redirects the request to this method, when the request given is “studentJson” and it can take only GET request which is denoted by method=RequestMethod.GET and produces JSON response only  which is mentioned with the help of produces(“application/json”) property of RequestMapping 
  • getStudentXml() Method :
    • Jaxb2RootElementHttpMessageConverter will be registered by Spring Context if JAXB dependency libraries are found. Java 7 has JAXB built-in and hence it will be automatiocally registered as well.
    • @RequestMapping annotation on top of getStudentXml() redirects the request to this method, when the request given is “studentXml” and it can take only GET request which is denoted by method=RequestMethod.GET and produces XML response only  which is mentioned with the help of produces(“application/xml”) property of RequestMapping 

 web.xml

The web.xml has everything about the application that a server needs to know, which is placed under the WEB-INF directory. <servlet-name> contains the name of the SpringConfiguration , when the DispatcherServlet is initialized the framework will try to load a configuration file [servlet-name]-servlet.xml” under the WEB-INF directory.

<?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: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>SpringMVCFormHandling</display-name>
   <welcome-file-list>
       <welcome-file>index.html</welcome-file>
       <welcome-file>index.htm</welcome-file>
       <welcome-file>index.jsp</welcome-file>
       <welcome-file>default.html</welcome-file>
       <welcome-file>default.htm</welcome-file>
       <welcome-file>default.jsp</welcome-file>
   </welcome-file-list>
   <servlet>
       <servlet-name>SpringConfig</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>SpringConfig</servlet-name>
      <url-pattern>/</url-pattern>
   </servlet-mapping>
</web-app>

SpringConfig-servlet.xml

The SpringConfig-servlet.xml is also placed under the WEB-INF directory.

  • <context:component-scan> will let the Spring Container to search for all the annotation under the package “com.javainteriviewpoint”.
  • <mvc:annotation-driven/> annotation will activate the @Controller, @RequestMapping, @Valid etc annotations.
<?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"
 xmlns:jee="http://www.springframework.org/schema/jee"
 xsi:schemaLocation=
 "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd" >
 
    <mvc:annotation-driven/>
 
    <context:component-scan base-package="com.javainterviewpoint"></context:component-scan>
 </beans>

Output

To Test I will be using POSTMAN client to test our service, you are free to choose your own.

XML Response

http://localhost:8080/SpringRESTTutorial/student/studentXml

Spring Rest Xml

JSON Response

http://localhost:8080/SpringRESTTutorial/student/studentJson

Spring Rest Json

Without Produces property

In our Spring REST Example service we have used produces property to produce JSON or XML responses.

@RequestMapping(value="/studentJson", method=RequestMethod.GET,
            produces="application/json")
    public Student getStudentJSON()
    {
        Student st = new Student();
        st.setName("JavaInterviewPoint");
        st.setAge("111");
        
        return st;
    }
    
    @RequestMapping(value="/studentXml", method=RequestMethod.GET,
            produces="application/xml")
    public Student getStudentXml()
    {
        Student st = new Student();
        st.setName("JavaInterviewPoint");
        st.setAge("999");
        
        return st;
    }

We can also create a Spring REST service with out having produces property, instead we need to give headers in the client. In my Client (POSTMAN) click on the headers tab, give Key as “Accept” and values as “application/json” if you need JSON response and “application/xml” for Xml response. In this way we can get both json and xml responses from a single method.

Our StudentService can be re-written like below

@RequestMapping(value="/studentJson", method=RequestMethod.GET)
    public Student getStudentJSON()
    {
        Student st = new Student();
        st.setName("JavaInterviewPoint");
        st.setAge("111");
        
        return st;
    }
    
    @RequestMapping(value="/studentXml", method=RequestMethod.GET)
    public Student getStudentXml()
    {
        Student st = new Student();
        st.setName("JavaInterviewPoint");
        st.setAge("999");
        
        return st;
    }

Output :

Url : http://localhost:8080/SpringRESTTutorial/student/studentJson

JSON Response

Spring Rest Json Response

XML Response

Spring Rest Xml Response

Note :

There are possibilities of getting the below Exception (IllegalAnnotationsException) in the model class, The fix is very simple add @XmlAccessorType(XmlAccessType.FIELD) on top of the class. so JAXB implementations will create bindings for fields.

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "age"
	this problem is related to the following location:
		at public java.lang.String com.javainterviewpoint.Student.getAge()
		at com.javainterviewpoint.Student
	this problem is related to the following location:
		at private java.lang.String com.javainterviewpoint.Student.age
		at com.javainterviewpoint.Student
Class has two properties of the same name "name"
	this problem is related to the following location:
		at public java.lang.String com.javainterviewpoint.Student.getName()
		at com.javainterviewpoint.Student
	this problem is related to the following location:
		at private java.lang.String com.javainterviewpoint.Student.name
		at com.javainterviewpoint.Student

Leave a Reply

Your email address will not be published. Required fields are marked *