5 minutes with – Spring REST

In this post I’ll speak about how building a RESTful service using Spring MVC and its *ViewResolver classes.

I’m going to build a service with the response informations in Xml and Json format using very few code line

My libraries

aopalliance-1.0.jar
commons-logging-1.1.1.jar
jackson-core-asl-1.5.3.jar
jackson-jaxrs-1.5.3.jar
jackson-mapper-asl-1.5.3.jar
jstl-1.1.2.jar
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-oxm-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar
standard-1.1.2.jar

I’m using Spring MVC with view Resolver BeanNameViewResolver. I’ve found it very easy to use and it let you take very good control on which view should be used in MVC system.


<?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: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/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="it.sample.samplerestspring.controller" />

	<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
		<property name="classesToBeBound">
			<list>
				<value>it.sample.samplerestspring.bean.Order</value>
				<value>it.sample.samplerestspring.bean.OrderList</value>
			</list>
		</property>
	</bean>

	<bean id="ds" class="it.sample.samplerestspring.data.OrderData" />

	<bean id="orderController" class="it.sample.samplerestspring.controller.OrderController" />

	<!-- Reader in base al BeanName (collegato alla chiamata URL) -->
	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />

	<bean id="orderViewJson" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

	<bean id="orderViewXml" class="org.springframework.web.servlet.view.xml.MarshallingView">
		<constructor-arg ref="jaxbMarshaller" />
	</bean>

</beans>

The orderViewJson is used to response the informations in json format. The orderViewXml is used to response the informations in xml format. In this last bean I set Jaxb2Marshaller object to allow serializing data in xml format.

package it.sample.samplerestspring.bean;
import it.sample.samplerestspring.controller.CustomDateSerializer;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@XmlRootElement(name="orders")
public class Order {
 private String orderId;
 private double invoice;
 private int itemNumber;
 private Date orderDate;
 public String getOrderId() {
  return orderId;
 }
 public void setOrderId(String orderId) {
  this.orderId = orderId;
 }
 public double getInvoice() {
  return invoice;
 }
 public void setInvoice(double invoice) {
  this.invoice = invoice;
 }
 public int getItemNumber() {
  return itemNumber;
 }
 public void setItemNumber(int itemNumber) {
  this.itemNumber = itemNumber;
 }
 @JsonSerialize(using = CustomDateSerializer.class)
 public Date getOrderDate() {
  return orderDate;
 }
 public void setOrderDate(Date orderDate) {
  this.orderDate = orderDate;
 }
}

The OrderList class

package it.sample.samplerestspring.bean;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="orders")
public class OrderList {
 private List<Order> items;
 public OrderList(){}
 
 public OrderList(List<Order> items)
 {
  this.items = items;
 }
 @XmlElement(name="order")
 public List<Order> getItems() {
  return items;
 }
 public void setItems(List<Order> items) {
  this.items = items;
 }
}

The Custom data serializer


package it.matrix.samplerestspring.controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

public class CustomDateSerializer extends JsonSerializer<Date> {

	@Override
	public void serialize(Date arg0, JsonGenerator arg1,
			SerializerProvider arg2) throws IOException,
			JsonProcessingException {

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
		String formattedDate = formatter.format(arg0);

		arg1.writeString(formattedDate);	
	}
}

Last, the 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:jsp="http://java.sun.com/xml/ns/javaee/jsp" 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>SampleRESTSpring</display-name>
  <servlet>
    <servlet-name>restspring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>restspring</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app>

The fake information are stored in OrderData class

package it.sample.samplerestspring.data;
import it.sample.samplerestspring.bean.Order;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class OrderData {
 // per semplicità aggiungiamo tutti gli oggetti all'interno di una mappa incapsulata
  private static List<Order> items = new ArrayList<Order>();
  
  // aggiungiamo qualche oggetto per simulare dei dati di esempio
  static {
   Order o1 = new Order();
   o1.setOrderId("AB2366");
   o1.setItemNumber(100);
   o1.setInvoice(1680.50);
   o1.setOrderDate(new Date());
   
   Order o2 = new Order();
   o2.setOrderId("CH6533");
   o2.setItemNumber(89);
   o2.setInvoice(200.02);
   o2.setOrderDate(new Date());
   
   Order o3 = new Order();
   o3.setOrderId("GH6522");
   o3.setItemNumber(200);
   o3.setInvoice(5600.50);
   o3.setOrderDate(new Date());
   
   items.add(o1);
   items.add(o2);
   items.add(o3);   
  }
  
  public List<Order> getItems()
  {
   return items;
  }
}

Now the controller file. In this file there are two annotated methods and the data object.

package it.sample.samplerestspring.controller;
import it.sample.samplerestspring.bean.OrderList;
import it.sample.samplerestspring.data.OrderData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class OrderController {
 
 @Autowired
 private OrderData ds;
 
 @RequestMapping(method=RequestMethod.GET, value="/xml/orders")
 public ModelAndView getTrainsXml() { 
  OrderList list = new OrderList(ds.getItems());
  return new ModelAndView("orderViewXml", "list", list);
 }
 
 @RequestMapping(method=RequestMethod.GET, value="/json/orders")
 public ModelAndView getTrainsJson() { 
  OrderList list = new OrderList(ds.getItems());
  return new ModelAndView("orderViewJson", "list", list);
 }
}

We can now launch the application server and browse the url /rest/xml/orders

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<orders>
  <order>
    <invoice>1680.5</invoice>
    <itemNumber>100</itemNumber>
    <orderDate>2012-05-25T16:07:29.131+02:00</orderDate>
    <orderId>AB2366</orderId>
  </order>
  <order>
    <invoice>200.02</invoice>
    <itemNumber>89</itemNumber>
    <orderDate>2012-05-25T16:07:29.131+02:00</orderDate>
    <orderId>CH6533</orderId>
  </order>
  <order>
    <invoice>5600.5</invoice>
    <itemNumber>200</itemNumber>
    <orderDate>2012-05-25T16:07:29.131+02:00</orderDate>
    <orderId>GH6522</orderId>
  </order>
</orders>

The other url /rest/json/orders is about json format.

{"list":
  {"items":
    [{"orderId":"AB2366","invoice":1680.5,"itemNumber":100,"orderDate":"2012-05-25T16:07:29.131+0200"},
    {"orderId":"CH6533","invoice":200.02,"itemNumber":89,"orderDate":"2012-05-25T16:07:29.131+0200"},
    {"orderId":"GH6522","invoice":5600.5,"itemNumber":200,"orderDate":"2012-05-25T16:07:29.131+0200"}]
  }
}

In summary, you can use and build org.springframework.web.servlet.view.* viewer, or build your own viewer, to show all the information data you need.

Advertisements

2 thoughts on “5 minutes with – Spring REST

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s