Develop Restful web services using Spring MVC
From Wikipedia: REST-style architectures consist of clients and servers. Clients initiate requests to servers; servers process requests and return appropriate responses. Requests and responses are built around the transfer of representations of resources. A resource can be essentially any coherent and meaningful concept that may be addressed.
For those who have never read about Rest this description of Rest architecture could seem something strange and bit complicated.
Let’s start with a simple Spring MVC application created with Spring MVC template. Not much secret here, you will have a servlet-context.xml where component-scan, annotation-driven and InternalResourceViewResolver are registered.
<?xml version="1.0" encoding="UTF-8" ?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <context:component-scan base-package="org.springframework.rest" /> </beans:beans>
Next step is defining Character class. A simple POJO with four attributes. Class is converted to its XML representation using Jaxb annotation. Jaxb allows developers to map Java classes to XML representations and viceversa.
package org.springframework.rest; import java.net.URL; import org.codehaus.jackson.annotate.JsonAutoDetect; @XmlRootElement public final class Character { private int id; private String name; private boolean isHuman; private URL characterUrl; protected Character() { } public Character(int id, String name, boolean isHuman, URL characterUrl) { super(); this.id = id; this.name = name; this.isHuman = isHuman; this.characterUrl = characterUrl; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isHuman() { return isHuman; } public void setHuman(boolean isHuman) { this.isHuman = isHuman; } public URL getCharacterUrl() { return characterUrl; } public void setCharacterUrl(URL characterUrl) { this.characterUrl = characterUrl; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Character other = (Character) obj; if (id != other.id) return false; return true; } }
And finally the most important class in Spring MVC, “The Controller“. Controller will be the responsible of implementing required operations of Character resource. In current case only GET is implemented, the other operations would be similar. Let’s see the code:
@Controller public class HomeController { private static final Map<Integer, Character> characters = new HashMap<Integer, Character>(); static { try { characters.put(1, new Character(1, "Totoro", false, new URL("http://animeonly.org/albums/VISINAUJI/EGIO/fourth/Mon-Voisin-Totoro/normal_totoro_001.jpg"))); characters.put(2, new Character(2, "Satsuki Kusakabe", true, new URL("http://profile.ak.fbcdn.net/hprofile-ak-ash2/48980_1802552968_7286_n.jpg"))); characters.put(3, new Character(3, "Therru", false, new URL("http://28.media.tumblr.com/tumblr_lj4ctjKA8Y1qdvyqpo1_400.jpg"))); } catch (MalformedURLException e) { e.printStackTrace(); } } /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/characters/{characterId}", method = RequestMethod.GET) @ResponseBody public Character findCharacter(@PathVariable int characterId) { return characters.get(characterId); } }
First part is a map where all characters are stored. I have used this approach to not focus in data access. Then findCharacter method that is called when URI is /characters/{characterId}. This is a URI template and is a URI-like string, containing one or more variable names, which can be accessed using @PathVariable annotation. So when you are accessing to /characters/1 parameter characterId is bound to 1.
Last important part is @ResponseBody annotation. This annotation can be put on a method and indicates that the return type should be written straight to the HTTP response body, and not placed in a Model, or interpreted as a view name as standard behaviour of Spring MVC. So findCharacter method returns a Character object.
And that’s all if you execute this code, and for example you enter URI http://localhost:8080/RestServer/characters/1 the output (using RestClient UI) will be:
And now is when you are wondering, ¿If I am returning a Character object and output is a XML, where is conversion between object and XML? So easy, let me introduce a new concept: HttpMessageConverters. HttpMessageConverter is responsible for converting from HTTP request message to an object and converting from an object to HTTP response body. Next HttpMessageConverters are registered by default:
CONCLUSIONS
Of course this is a very simple application with only one operation, but it gives you an idea of how to develop Restful web services using Spring MVC. It is a matter of time of writing all your required operations using same approach that I have used with GET.
Arriving at this point I think that all of us have arrived to same conclusion. Annotations are really really powerful, and Spring MVC fits perfectly for developing RESTful web services.
See you next time…
Reference: Develop Restful web services using Spring MVC from our JCG partner Alex Soto at the One Jar To Rule Them All blog.
Related Articles :
- jqGrid, REST, AJAX and Spring MVC Integration
- Java RESTful API integration testing
- Building a RESTful Web Service with Spring 3.1 and Java based Configuration, part 2
- Android JSON Parsing with Gson Revisited
- RESTful Web Services with RESTeasy JAX-RS on Tomcat 7 – Eclipse and Maven project
- Spring 3 RESTful Web Services
- Spring MVC Development – Quick Tutorial
Great, simple example on how to use Spring to achieve a RESTFul webservice. Thank you!
Great example! Saved a lot of time! Only diff is that I am using @Configuration classes for Spring and had to add marshalling classes manually. But: WORKS!
great thanks
Excellent!!
Is it possible for the client to request an XML or JSON format? Perhaps something like this…
http://localhost:8080/RestServer/characters/1?format=json
http://localhost:8080/RestServer/characters/1?format=xml
If you write .json or .xml at the end of the uri you will get a result in that format:
http://localhost:8080/RestServer/characters/1.json
http://localhost:8080/RestServer/characters/1.xml