The purpose of this tutorial is to explain how to do a minimal REST Application with Spring MVC in a Maven project.
This is illustrated by the creation of a REST Controller able to Create, Update, Delete some entity Computer.
So in this tutorial we will use this java class
public class Computer {
private long id;
private String brand;
private String model;
private String reference;
private String description;
// getter and setter ...
}
and some JSON computer objects as in this example :
{
"id":1,"reference":"MACR","description":"Test","model":"Macbook Air","brand":"Apple"
}
I will not talk here about how to do a REST service really REST compliant, about best practice, or explain what exactly REST is.
I will just show how to implement 4 Basic REST Http Methods with Spring MVC, and how configure Spring MVC to do this.
If you are in a rush you can go here : http://www.davidgimelle.com/src/SpringREST.zip, dowload this project, install it with Maven, deploy it on an application server and go there http://localhost:8080/SpringREST/rest/computer to see if it works. It should return the content of an empty json array []. But all the same it might be worth reading this first.
0) Introduction about REST and Spring MVC annotation in 10 lines
Spring MVC for REST uses the JSON format to exchange data with HTTP protocole. Spring MVC manages Http requests /responses and makes transformations JSON<->Java pojo.
REST uses mainly 4 Http methods GET, POST, PUT and DELETE. If you are new to REST you should read this paragraph in wikipedia : http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_services
Spring MVC provides some annotation to manage Http. In this tutorial i will use only 5 :
@Controller --> Declare a Spring MVC Controller
@RequestMapping("/computer") --> Map an URI with a controller or a method
@PathVariable --> Read a variable in an Uri and assign this value to a java variable
@RequestBody --> Declare a Pojo class to map the http request body
@ResponseBody --> Declare a Pojo class to generate Json content to return to the http client
1) Create a controller with a GET method
So let see the declaration of a Controller in Java.
The Class ComputerController is a controller to handle all REST requests about entities Computer.
// Declaration as this class as a controller
@Controller
// Declaration that this controller handles requests on uri */computer
@RequestMapping("/computer")
public class ComputerController {
// Stores computers
private static final ComputerStorage computerStorage = new ComputerStorage();
// Declare a method that handle all GET request on */computer
@RequestMapping(method = RequestMethod.GET)
// Return a list of computer to the http client
public @ResponseBody List<Computer> getComputers() {
return computerStorage.getAll();
}
}
2) Configure the application
It's a standard Spring mvc configuration, with nothing special for REST.
- Spring mvc must be declared in the web.xml :
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
The Servlet mapping of the mvc-dispatcher redirects all requests on */rest/* to Spring MVC.
So it's possible to request the computer controller by a GET on http://localhost:8080/SpringREST/rest/computer .
SpringREST is the default name of the application, you can change it when you deploy the war.
- The file mvc-dispatcher-servlet.xml discribes REST controllers. Because we use annotation base declaration of controllers, we just need to set witch packages contain controllers with the context:component-scan declaration.
<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-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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan
base-package="com.davidgimelle.springrest.tuto"
/>
<mvc:annotation-driven />
</beans>
<display-name>Spring REST Application</display-name>
3) Add methods POST, PUT and DELETE to the controller
Now complete the controller with 3 more methods.
- The POST method add one computer.
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public void addComputer(@RequestBody Computer computer) {
computerStorage.add(computer);
}
@RequestBody indicate to the server that the json content of the request is use to fill a new Computer instance.
@ResponseBody alone is required on void method to return no content to the REST Client .
- The PUT method update one computer.
@RequestMapping(value="{id}",method = RequestMethod.PUT)
@ResponseBody
public void putComputer(@PathVariable long id, @RequestBody Computer computer) {
computer.setId(id);
computerStorage.update(computer);
}
Following the rest convention, the id of the entity to update is set in the uri like in this example : PUT on http://localhost:8080/SpringREST/rest/computer/6 .
Set the id in the uri and not in the json content respect the REST convention. You can see the PUT convention here : http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_services .
@RequestMapping completes the request mapping of the controller with the id and the @PathVariable assigns the value to the long id.
-A DELETE method delete a computer.
@RequestMapping(value="{id}", method = RequestMethod.DELETE)
@ResponseBody
public void deleteComputer(@PathVariable long id) {
computerStorage.delete(id);
}
4) How to test it ?
You can use RestClient, a firefox's plugin to test the Rest application : https://addons.mozilla.org/en-US/firefox/addon/restclient/ .
- Start by testing a GET on http://localhost:8080/SpringREST/rest/computer .
The response body (Visible in the panel Response Body of Rest Client Plugin) will be an empty array because there is no data yet : []
- Test POST http://localhost:8080/SpringREST/rest/computer
Before sending the request, add an http header Content-Type with the button Add Request Header of Rest client : Content-Type:application/json; charset=utf-8
add a JSON content in the request body
{"reference":"MAC","description":"Test","model":"MB Pro","brand":"Apple"}
- Now the GET should return
[{"id":1,"reference":"MAC","description":"Test","model":"MB Pro","brand":"Apple"}]
- Do a second POST
- Now the GET should return
[{"id":1,"reference":"MAC","description":"Test","model":"MB Pro","brand":"Apple"}, {"id":2,"reference":"MAC","description":"Test","model":"MB Pro","brand":"Apple"}]
- Delete a computer with a PUT on http://localhost:8080/SpringREST/rest/computer/2
- GET return now
[{"id":1,"reference":"MAC","description":"Test","model":"MB Pro","brand":"Apple"}]
- Update a computer with a PUT on http://localhost:8080/SpringREST/rest/computer/1 with
Content-Type:application/json; charset=utf-8
add a JSON content in the request body
{"reference":"MACR","description":"Test","model":"Macbook Air","brand":"Apple"}
- GET return
[{"id":1,"reference":"MACR","description":"Test","model":"Macbook Air","brand":"Apple"}]
5) Jackson JSON Processor
Jakson JOSN Processor is used by Spring to make the mapping JSON <-> Java Object. Since spring 3.0.2, it uses by default if it presents in the classpath of the application.
6) How to use Maven ?
It's the same declaration that for Spring MVC with a dependency on JSON Processor :
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.1</version>
</dependency>
You can find the entire pom.xml it in the source of this article.
7) Where are the source of this article ?
You can dowload it here : http://www.davidgimelle.com/src/SpringREST.zip
Thanks for reading. The next time i will talk about more advanced features such as Handle Error or Http parameters.
Links
REST : http://en.wikipedia.org/wiki/Representational_state_transfer
An other tutorial : http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example
Springsource example : http://static.springsource.org/spring-security/site/petclinic-tutorial.html
Jackson JSON processor : http://jackson.codehaus.org
REST and HTTP : http://www.packetizer.com/ws/rest.html
Firefox Rest Client : https://addons.mozilla.org/en-US/firefox/addon/restclient
Technical Specifications
Spring mvc 3.0.5 use Jackson JSON processor 1.7.1 to marchal/unmarchal Java/JSON
Tested 11th March 2012 with Spring 3.0.5, Glassfish 3.1.1, Java 1.6.0_29, Mac OSX 10.6.8