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 :
- Create a Dynamic Web Project SpringRESTTutorial and create a package for our src files “com.javainterviewpoint“
- 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 - Create the Java classes Student.java and StudentService.java under com.javainterviewpoint folder.
- 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> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/Jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> </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
JSON Response
http://localhost:8080/SpringRESTTutorial/student/studentJson
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
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
Ajay kumar Maheshbhai Jayswal says
[
student:{
“name”:”abc”,
“age”:5
},
{“name”:”fff”,
“age”:2
}
}
]
i want this output
javainterviewpoint says
All you have to do is create an ArrayList and add multiple student objects to the ArrayList and return the ArrayList as output