Spring framework helps us to create good restful web service using the Spring's annotation based MVC framework.
In this example, I am using a) Spring Framework 3.1.1 b) maven 3.0.5 c) Apache Tomcat 6
Download full source code [click on file-> download in google drive]
reference:
http://briansjavablog.blogspot.ae/2012/08/rest-services-with-spring.html
Restful web services by Oreily - http://www.amazon.com/dp/0596529260/ref=tsm_1_fb_lk
In this example, I am using a) Spring Framework 3.1.1 b) maven 3.0.5 c) Apache Tomcat 6
Spring Controller class
This class will serve as the restful handler class. In this class the methods getStudent(), getAllStudents()have the annotation RequestMapping maps the incoming HTTP request which matches the format /rest/student/{studId} will redirect to the method getStudent(), like that /rest/student/ will redirect to the getAllStudents() method. method = RequestMethod.GET says that the HTTP GET method process by this method. These method returns Student object in the JSON format to the client.StudentController.java
package com.smash.webservices.rest; import java.util.List; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; 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.servlet.ModelAndView; import org.springframework.web.servlet.View; import com.smash.domain.Student; import com.smash.services.StudentService; /** * StudentController class will expose a series of Restful end points */ @Controller public class StudentController { @Autowired private StudentService studService; @Autowired private View jsonView; private static final String DATA_FIELD = "data"; private static final String ERROR_FIELD = "error"; private static final Logger log = Logger.getLogger(StudentController.class); @RequestMapping(value = "/rest/student/", method = RequestMethod.GET) public ModelAndView getAllStudents() { ListstudentList = null; try { studentList = studService.getAllStudents(); } catch (Exception e) { String sMessage = "Error invoking getStudent"; return getErrorJSON(String.format(sMessage, e.toString())); } log.debug("Returing Student: " + studentList.toString()); return new ModelAndView(jsonView, DATA_FIELD, studentList); } @RequestMapping(value = "/rest/student/{studId}", method = RequestMethod.GET) public ModelAndView getStudent(@PathVariable("studId") String studId) { Student student = null; /* validate student Id parameter */ if (isEmpty(studId) || studId.length() < 2) { String sMessage = "Error invoking getStudent - Invalid student Id parameter"; return getErrorJSON(sMessage); } try { student = studService.getStudById(studId); } catch (Exception e) { String sMessage = "Error invoking getStudent. [%1$s]"; return getErrorJSON(String.format(sMessage, e.toString())); } log.debug("Returing Student: " + student.toString()); return new ModelAndView(jsonView, DATA_FIELD, student); } public static boolean isEmpty(String id) { return (null == id) || id.trim().length() == 0; } /** * Create an error REST response. * @param sMessage * @return */ private ModelAndView getErrorJSON(String sMessage) { return new ModelAndView(jsonView, ERROR_FIELD, sMessage); } /** * Injector methods. * * @param studentService_p * the new student service */ public void setStudentService(StudentService studService_p) { studService = studService_p; } }
Service Class
Rest handler class calls the service method to get the data for the view.
StudentService.java
StudentService.java
package com.smash.services; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; import com.smash.domain.Student; @Service public class StudentService { /** * Returns the student details based on ID * @param studentId * @return */ public Student getStudById(String studentId) { Student student = new Student(); student.setStudentId(studentId); student.setName("mark"); student.setGender('M'); student.setAddress("Dubai"); return student; } /** * Returns all student details.From this class you can connect to database through impl-*ementation classes to get the real data * @param studentId * @return */ public ListgetAllStudents() { Student student = new Student(); student.setStudentId("101"); student.setName("Mark"); student.setGender('M'); student.setAddress("Dubai"); List sList= new ArrayList (); sList.add(student); student = new Student(); student.setStudentId("102"); student.setName("Steve"); student.setGender('M'); student.setAddress("Dubai"); sList.add(student); return sList; } }
The Domain Class
Student.java
package com.smash.domain; public class Student { private String studentId; private String name; private char gender; private String address; /*get and set methods here*/ }
Web.xml file
<?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>REST Sample</display-name> <!-- Main configuration file for this Spring web application. --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/rest-services-config.xml </param-value> </context-param> <!-- Loads the Spring web application context using the config file defined above. --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Define the Spring Dispatcher Servlet for the REST services. The 'contextConfiguration' param with an empty value means that the Spring Context won't try to load a default file called restservices-servlet.xml --> <servlet> <servlet-name>restservices</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- This Servlet mapping means that this Servlet will handle all incoming requests --> <servlet-mapping> <servlet-name>restservices</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Restful services configuration file
rest-services-config.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:oxm="http://www.springframework.org/schema/oxm" xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc-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/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <!-- Enables automatic mapping of fund objects to and from JSON --> <mvc:annotation-driven/> <!-- Setup spring to pull in @Controller, @RequestMapping, etc Configuration scans specified packages for classes configured as Spring managed beans and automatically sets up objects annotated with @Controller, @Service etc. --> <context:component-scan base-package="com.smash.webservices.rest" /> <context:component-scan base-package="com.smash.services" /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <!-- Configures view for returning JSON to the client --> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="contentType" value="text/plain"/> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <util:list id="beanList"> <ref bean="jsonMessageConverter"/> </util:list> </property> </bean> <!-- Converts JSON to POJO and vice versa --> <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> </beans>
Output of the restful web service
- Get all the student details. URL:
http://localhost:8080/rest-sample/rest/student/
- Get the student based on student Id, GET operation, URL:
http://localhost:8080/rest-sample/rest/student/11
Download full source code [click on file-> download in google drive]
reference:
http://briansjavablog.blogspot.ae/2012/08/rest-services-with-spring.html
Restful web services by Oreily - http://www.amazon.com/dp/0596529260/ref=tsm_1_fb_lk
Hi, this is a very good example. Could you provide this example with JPA/mysql? Thanks in advance.
ReplyDeleteI got this error "The constructor ModelAndView(View, String, List) is undefined"
ReplyDeletefrom : return new ModelAndView(jsonView, DATA_FIELD, studentList);
Hi,
ReplyDeleteCan you tell me what is the spring version you are using?
Please post the code for a sample client to make it easier to understand
ReplyDelete