Enterprise Java

Develop Restful web services using Spring MVC

REST INTRODUCTION

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.

As you have read the most important thing in Rest architecture is the existance of a resource. This resource  can be anything (typically required information requested by client) that can be identified with a global identifier (URI in case of HTTP). In order to manipulate these resources, client communicates using standard interfaces (like HTTP) and exchange representations of these resources (using HTML, XML, …).
Note that Rest does not force you to use any specific network protocol nor how resources are identified.

For those who have never read about Rest this description of Rest architecture could seem something strange and bit complicated. 

A RESTful web service is a simple web service implemented using HTTP and the principles of REST. URI is defined as global identified, communication interface is HTTP and resource representation can be any valid Internet media type like JSON, XML or YAML. The set of operations that can be executed to resources depend on HTTP Methods and are (GET – retrieving/listing, PUT – replacing/updating, POST – creating and DELETE – deleting).
HANDS ON WORK
Let’s create our first Rest application with help of Spring MVC. Imagine an application that has a database of manga characters, and you want to provide a Rest interface so clients can retrieve characters following a RESTful strategy.
First thing to do is identify the resource. In this case it is easy, “a character“. Next step is finding a URI that determines unequivocally a character. Easy too de facto rule can be applied here. This rule suggests that a unique URI can be <host>/<applicationname>/<resourceName>s/<id> in our case to return (GET) character with id 1 the URI would be “http://localhost:8080/RestServer/characters/1“. If no identifier is present all characters should be retrieved. If instead of GET, POST is used, a character with id “1” would be inserted. And finally decide which Internet media type is required, in this case doesn’t matter because we are implementing both client and server so initially XML will be used.
CODING
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:

– ByteArrayHttpMessageConverter
– StringHttpMessageConverter
– ResourceHttpMessageConverter
– SourceHttpMessageConverter
– XmlAwareHttpMessageConverter
– Jaxb2RootElementHttpMessageConverter
– MappingJacksonHttpMessageConverter
So now you understand why works perfectly. When you are returning Character instance, Jaxb2RootElementHttpMessageConverter using canWrite method checks if class contains XmlRootElement annotation. If class is annotated, write method is called. In this case Jaxb marshaller is called, and XML is returned. Same from XML to object but using Jaxb unmarshaller class.
So easy, no complicated configurations, no complicated mappings, no unclear code, and you only need to worry about your model objects, not in conversion. But let me introduce one change. Now instead of returning XML we want to return JSON.
Change could not be easier, add Jackson library to pom.xml and change @XmlRootElement to @JsonAutoDetect. And now MappingJacksonHttpMessageConverter will handle this object and will transform Character instance to JSON protocol using Jackson library. Only changing one line of code!!!
And now output will be:

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…

Download Code.

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 :

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sulaiman Rafiq
Sulaiman Rafiq
12 years ago

Great, simple  example on how to use Spring to achieve a RESTFul webservice. Thank you!

Mircea Stanciu
11 years ago

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!

Amol Chavan
Amol Chavan
11 years ago

great thanks

Kumar
Kumar
10 years ago

Excellent!!

Adam
Adam
9 years ago

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

Mark
9 years ago

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

Back to top button