The Service :
Create a project with Maven for Eclipse Dynamic Web Project from here.
Here I have used Spring Annotation up to my knowledge. I believe there are more things which can be annotated.
The Deployment Descriptor (web.xml) is the simplest
<?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"
version="2.5" id="WebApp_1291891438549">
<display-name>Spring REST Example1</display-name>
<servlet>
<servlet-name>person</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>person</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
So we must have the person-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
<context:component-scan base-package="com.dyuti.spring.rest" />
<!-- Format Output -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean id="personXmlView"
class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="autodetectAnnotations" value="true" />
</bean>
</constructor-arg>
</bean>
<!-- -->
<!-- Convert Input -->
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="marshallingHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="jaxb2Marshaller" />
<property name="unmarshaller" ref="jaxb2Marshaller" />
</bean>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.dyuti.spring.rest.domain.Person</value>
</list>
</property>
</bean>
<!-- -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/person" />
<property name="username" value="root" />
<property name="password" value="*****" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>com.dyuti.spring.rest.domain.Person</value>
</list>
</property>
<property name="hibernateProperties">
<value>hibernate.dialect=org.hibernate.dialect.MySQLDialect</value>
</property>
</bean>
<bean id="personDao" class="com.dyuti.spring.rest.dao.PersonDaoHibImpl">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</beans>
We use org.springframework.oxm.xstream.XStreamMarshaller for converting Java Object to XML for sending through HTTP, and also converting HTTP XML data to corresponding Java Object.
The simple Person objec
package com.dyuti.spring.rest.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XmlRootElement
@XStreamAlias("person")
@Entity
@Table(name = "person")
public class Person implements Serializable {
private static final long serialVersionUID = 2675617253130859687L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column
private String name;
@Column
private int age;
// Generate getter & setter here
}
Now the DAO and the Hibernate Implementation
package com.dyuti.spring.rest.dao;
import com.dyuti.spring.rest.domain.Person;
public interface PersonDao {
public boolean save(Person person);
public Person get(int id);
}
package com.dyuti.spring.rest.dao;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import com.dyuti.spring.rest.domain.Person;
@Repository("personDao")
public class PersonDaoHibImpl extends HibernateDaoSupport implements PersonDao {
@Override
public boolean save(Person person) {
int id = (Integer) getHibernateTemplate().save(person);
return id > 0 ? true : false;
}
@Override
public Person get(int id) {
return (Person) getHibernateTemplate().get(Person.class, id);
}
}
And the service and its implementation
package com.dyuti.spring.rest.service;
import com.dyuti.spring.rest.domain.Person;
public interface PersonService {
public boolean savePerson(Person p);
public Person getPerson(int id);
}
package com.dyuti.spring.rest.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dyuti.spring.rest.dao.PersonDao;
import com.dyuti.spring.rest.domain.Person;
@Service("personService")
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonDao personDao;
@Override
public boolean savePerson(Person person) {
return personDao.save(person);
}
@Override
public Person getPerson(int id) {
return personDao.get(id);
}
}
The controller is the entry point and also the provider of the web service.
package com.dyuti.spring.rest.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.dyuti.spring.rest.domain.Person;
import com.dyuti.spring.rest.service.PersonService;
@Controller
public class PersonController {
@Autowired
private PersonService personService;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ModelAndView getPerson(@PathVariable int id) {
Person person = personService.getPerson(id);
return new ModelAndView("personXmlView", BindingResult.MODEL_KEY_PREFIX
+ "person", person);
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ModelAndView addPerson(@RequestBody Person person) {
boolean result = personService.savePerson(person);
return new ModelAndView("personXmlView", BindingResult.MODEL_KEY_PREFIX
+ "person", result);
}
}
Finally the pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dyuti.spring.rest</groupId>
<artifactId>SpringREST</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringREST</name>
<url>http://maven.apache.org</url>
<build>
<finalName>SpringREST</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- configure the plugin here -->
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp</directory>
<filtering>false</filtering>
<excludes>
<exclude>WEB-INF/lib/*</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons.beanutils.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons.collections.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>1.6</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
<exclusions>
<exclusion>
<artifactId>ehcache</artifactId>
<groupId>net.sf.ehcache</groupId>
</exclusion>
<exclusion>
<artifactId>commons-collections</artifactId>
<groupId>commons-collections</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernate.annotations.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>${hibernate.annotations.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.8</version>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>commons-dbcp-all</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>${jpa.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<spring.version>3.0.0.RELEASE</spring.version>
<java.version>1.6</java.version>
<servlet-api.version>2.5.0</servlet-api.version>
<hibernate.annotations.version>3.3.0.ga</hibernate.annotations.version>
<hibernate.version>3.2.6.ga</hibernate.version>
<jpa.version>1.0</jpa.version>
<commons.beanutils.version>1.7.0</commons.beanutils.version>
<commons.collections.version>3.2</commons.collections.version>
<commons.io.version>1.3.2</commons.io.version>
<commons.lang.version>2.3</commons.lang.version>
</properties>
</project>
So, the project is set up and deploy it on Tomcat.
The client :
The RestClient provided by Spring makes life very simple creating REST consumer.
Create another project (not necessary a web project, client can be anything, even if Ajax).
Create the same Person object from above.
Lets create the Spring context file, resides in the same package of the loader class under resource folder.
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
<context:component-scan base-package="com.dyuti.spring.rest" />
<bean id="personSave" class="com.dyuti.spring.rest.controller.SavePerson">
<property name="restTemplate">
<ref bean="restTemplate" />
</property>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"></bean>
</beans>
And the client class
package com.dyuti.spring.rest.controller;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.dyuti.spring.rest.domain.Person;
@Component
public class SavePerson {
private RestTemplate restTemplate;
private String restURL = "http://localhost:8080/SpringREST/";
public void sendPerson() {
Person person = new Person();
person.setName("client");
person.setAge(12);
person.setId(3);
Person p = restTemplate.getForObject(restURL + "2", Person.class);
System.out.println(p.getName());
String result = restTemplate.postForObject(restURL + "add", person,
String.class);
System.out.println(result);
}
public void setRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
}
Run the client
package com.dyuti.spring.rest.controller;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RunRest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml", RunRest.class);
SavePerson savePerson = applicationContext.getBean("personSave",
SavePerson.class);
savePerson.sendPerson();
}
}
I have used the same pom.xml for this project, which may require less packages.