Spring Remoting Support with Http Invoker
Spring supports HTTP invoker infrastructure via HttpInvokerProxyFactoryBean and HttpInvokerServiceExporter. HttpInvokerServiceExporter that exports the specified service bean as HTTP invoker service endpoint, accessible via an HTTP invoker proxy. HttpInvokerProxyFactoryBean is a factory bean for HTTP invoker proxies.
Also Spring Remoting Support & RMI article is offered for Spring Remoting introduction and RMI Service & Client sample project.
Let us look at Spring Remoting Support to develop Http Invoker Service & Client.
Used Technologies :
- JDK 1.6.0_31
- Spring 3.1.1
- Tomcat 7.0
- Maven 3.0.2
STEP 1 : CREATE MAVEN PROJECT
A maven project is created as below. (It can be created by using Maven or IDE Plug-in).
STEP 2 : LIBRARIES
Spring dependencies are added to Maven’ s pom.xml.
<!-- Spring 3.1.x dependencies --> <properties> <spring.version>3.1.1.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-remoting</artifactId> <version>2.0.8</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> <dependencies>
STEP 3 : CREATE USER CLASS
A new User Class is created.
package com.otv.user; import java.io.Serializable; /** * User Bean * * @author onlinetechvision.com * @since 24 Feb 2012 * @version 1.0.0 * */ public class User implements Serializable { private long id; private String name; private String surname; /** * Get User Id * * @return long id */ public long getId() { return id; } /** * Set User Id * * @param long id */ public void setId(long id) { this.id = id; } /** * Get User Name * * @return long id */ public String getName() { return name; } /** * Set User Name * * @param String name */ public void setName(String name) { this.name = name; } /** * Get User Surname * * @return long id */ public String getSurname() { return surname; } /** * Set User Surname * * @param String surname */ public void setSurname(String surname) { this.surname = surname; } @Override public String toString() { StringBuilder strBuilder = new StringBuilder(); strBuilder.append("Id : ").append(getId()); strBuilder.append(", Name : ").append(getName()); strBuilder.append(", Surname : ").append(getSurname()); return strBuilder.toString(); } }
STEP 4 : CREATE ICacheService INTERFACE
ICacheService Interface representing a remote cache service interface, is created.
package com.otv.cache.service; import java.util.concurrent.ConcurrentHashMap; import com.otv.user.User; /** * Cache Service Interface * * @author onlinetechvision.com * @since 10 Mar 2012 * @version 1.0.0 * */ public interface ICacheService { /** * Get User Map * * @return ConcurrentHashMap User Map */ public ConcurrentHashMap<Long, User> getUserMap(); }
STEP 5 : CREATE CacheService CLASS
CacheService Class is created by implementing ICacheService Interface. It provides access to the remote cache…
package com.otv.cache.service; import java.util.concurrent.ConcurrentHashMap; import com.otv.user.User; /** * Cache Service Implementation * * @author onlinetechvision.com * @since 10 Mar 2012 * @version 1.0.0 * */ public class CacheService implements ICacheService { //User Map is injected... ConcurrentHashMap<Long, User> userMap; /** * Get User Map * * @return ConcurrentHashMap User Map */ public ConcurrentHashMap<Long, User> getUserMap() { return userMap; } /** * Set User Map * * @param ConcurrentHashMap User Map */ public void setUserMap(ConcurrentHashMap<Long, User> userMap) { this.userMap = userMap; } }
STEP 6 : CREATE IHttpUserService INTERFACE
IHttpUserService representing Http user service interface, is created. Also, it provides remote methods for the Http Clients…
package com.otv.http.server; import java.util.List; import com.otv.user.User; /** * Http User Service Interface * * @author onlinetechvision.com * @since 10 Mar 2012 * @version 1.0.0 * */ public interface IHttpUserService { /** * Add User * * @param User user * @return boolean response of the method */ public boolean addUser(User user); /** * Delete User * * @param User user * @return boolean response of the method */ public boolean deleteUser(User user); /** * Get User List * * @return List user list */ public List<User> getUserList(); }
STEP 7 : CREATE HttpUserService CLASS
HttpUserService Class is created by implementing IHttpUserService Interface.
package com.otv.http.server; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.otv.cache.service.ICacheService; import com.otv.user.User; /** * Http User Service Implementation * * @author onlinetechvision.com * @since 10 Mar 2012 * @version 1.0.0 * */ public class HttpUserService implements IHttpUserService { private static Logger logger = Logger.getLogger(HttpUserService.class); //Remote Cache Service is injected... ICacheService cacheService; /** * Add User * * @param User user * @return boolean response of the method */ public boolean addUser(User user) { getCacheService().getUserMap().put(user.getId(), user); logger.debug("User has been added to cache. User : "+getCacheService().getUserMap().get(user.getId())); return true; } /** * Delete User * * @param User user * @return boolean response of the method */ public boolean deleteUser(User user) { getCacheService().getUserMap().remove(user.getId()); logger.debug("User has been deleted from cache. User : "+user); return true; } /** * Get User List * * @return List user list */ public List<User> getUserList() { List<User> list = new ArrayList<User>(); list.addAll(getCacheService().getUserMap().values()); logger.debug("User List : "+list); return list; } /** * Get Remote Cache Service * * @return ICacheService Remote Cache Service */ public ICacheService getCacheService() { return cacheService; } /** * Set Remote Cache Service * * @param ICacheService Remote Cache Service */ public void setCacheService(ICacheService cacheService) { this.cacheService = cacheService; } }
STEP 8 : CREATE HttpUserService-servlet.xml
HttpUserService Application Context is shown as follows. This xml has to be named as your_servlet_name-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="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"> <!-- User Map Declaration --> <bean id="UserMap" class="java.util.concurrent.ConcurrentHashMap" /> <!-- Cache Service Declaration --> <bean id="CacheService" class="com.otv.cache.service.CacheService"> <property name="userMap" ref="UserMap"/> </bean> <!-- Http User Service Bean Declaration --> <bean id="HttpUserService" class="com.otv.http.server.HttpUserService" > <property name="cacheService" ref="CacheService"/> </bean> <!-- Http Invoker Service Declaration --> <bean id="HttpUserServiceExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> <!-- service represents Service Impl --> <property name="service" ref="HttpUserService"/> <!-- serviceInterface represents Http Service Interface which is exposed --> <property name="serviceInterface" value="com.otv.http.server.IHttpUserService"/> </bean> <!-- Mapping configurations from URLs to request handler beans --> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/HttpUserService">HttpUserServiceExporter</prop> </props> </property> </bean> </beans>
STEP 9 : CREATE web.xml
web.xml is configured as follows :
<?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" id="WebApp_ID" version="2.5"> <display-name>OTV_SpringHttpInvoker</display-name> <!-- Spring Context Configuration' s Path definition --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/HttpUserService-servlet.xml </param-value> </context-param> <!-- The Bootstrap listener to start up and shut down Spring's root WebApplicationContext. It is registered to Servlet Container --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Central dispatcher for HTTP-based remote service exporters. Dispatches to registered handlers for processing web requests.--> <servlet> <servlet-name>HttpUserService</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <!-- Servlets should be registered with servlet container and mapped with url for the http requests. --> <servlet-mapping> <servlet-name>HttpUserService</servlet-name> <url-pattern>/HttpUserService</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/pages/index.xhtml</welcome-file> </welcome-file-list> </web-app>
STEP 10 : CREATE HttpUserServiceClient CLASS
HttpUserServiceClient Class is created. It calls the Remote Http User Service and performs user operations.
package com.otv.http.client; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.otv.http.server.IHttpUserService; import com.otv.user.User; /** * Http User Service Client * * @author onlinetechvision.com * @since 24 Feb 2012 * @version 1.0.0 * */ public class HttpUserServiceClient { private static Logger logger = Logger.getLogger(HttpUserServiceClient.class); /** * Main method of the Http User Service Client * */ public static void main(String[] args) { logger.debug("Http User Service Client is starting..."); //Http Client Application Context is started... ApplicationContext context = new ClassPathXmlApplicationContext("httpClientAppContext.xml"); //Remote User Service is called via Http Client Application Context... IHttpUserService httpClient = (IHttpUserService) context.getBean("HttpUserService"); //New User is created... User user = new User(); user.setId(1); user.setName("Bruce"); user.setSurname("Willis"); //The user is added to the remote cache... httpClient.addUser(user); //The users are gotten via remote cache... httpClient.getUserList(); //The user is deleted from remote cache... httpClient.deleteUser(user); logger.debug("Http User Service Client is stopped..."); } }
STEP 11 : CREATE httpClientAppContext.xml
Http Client Application Context is shown as follows :
<beans xmlns="http://www.springframework.org/schema/beans" 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 Invoker Client Declaration --> <bean id="HttpUserService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> <!-- serviceUrl demonstrates Http Service Url which is called--> <property name="serviceUrl" value="http://remotehost:port/OTV_SpringHttpInvoker-0.0.1-SNAPSHOT/HttpUserService"/> <!-- serviceInterface demonstrates Http Service Interface which is called --> <property name="serviceInterface" value="com.otv.http.server.IHttpUserService"/> </bean> </beans>
STEP 12 : DEPLOY PROJECT
After OTV_SpringHttpInvoker Project is deployed to Tomcat, Http User Service Client is started and output logs are shown as follows :
.... 15.03.2012 21:26:41 DEBUG (DispatcherServlet.java:819) - DispatcherServlet with name 'HttpUserService' processing POST request for [/OTV_SpringHttpInvoker-0.0.1-SNAPSHOT/HttpUserService] 15.03.2012 21:26:41 DEBUG (AbstractUrlHandlerMapping.java:124) - Mapping [/HttpUserService] to HandlerExecutionChain with handler [org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter@f9104a] and 1 interceptor 15.03.2012 21:26:41 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming HttpInvokerServiceExporter remote call: com.otv.http.server.IHttpUserService.addUser 15.03.2012 21:26:41 DEBUG (HttpUserService.java:33) - User has been added to cache. User : Id : 1, Name : Bruce, Surname : Willis 15.03.2012 21:26:41 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of HttpInvokerServiceExporter remote call: com.otv.http.server.IHttpUserService.addUser 15.03.2012 21:26:41 DEBUG (DispatcherServlet.java:957) - Null ModelAndView returned to DispatcherServlet with name 'HttpUserService': assuming HandlerAdapter completed request handling 15.03.2012 21:26:41 DEBUG (FrameworkServlet.java:913) - Successfully completed request 15.03.2012 21:26:41 DEBUG (DispatcherServlet.java:819) - DispatcherServlet with name 'HttpUserService' processing POST request for [/OTV_SpringHttpInvoker-0.0.1-SNAPSHOT/HttpUserService] 15.03.2012 21:26:41 DEBUG (AbstractUrlHandlerMapping.java:124) - Mapping [/HttpUserService] to HandlerExecutionChain with handler [org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter@f9104a] and 1 interceptor 15.03.2012 21:26:41 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming HttpInvokerServiceExporter remote call: com.otv.http.server.IHttpUserService.getUserList 15.03.2012 21:26:41 DEBUG (HttpUserService.java:57) - User List : [Id : 1, Name : Bruce, Surname : Willis] 15.03.2012 21:26:41 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of HttpInvokerServiceExporter remote call: com.otv.http.server.IHttpUserService.getUserList 15.03.2012 21:26:41 DEBUG (DispatcherServlet.java:957) - Null ModelAndView returned to DispatcherServlet with name 'HttpUserService': assuming HandlerAdapter completed request handling 15.03.2012 21:26:41 DEBUG (FrameworkServlet.java:913) - Successfully completed request 15.03.2012 21:26:41 DEBUG (DispatcherServlet.java:819) - DispatcherServlet with name 'HttpUserService' processing POST request for [/OTV_SpringHttpInvoker-0.0.1-SNAPSHOT/HttpUserService] 15.03.2012 21:26:41 DEBUG (AbstractUrlHandlerMapping.java:124) - Mapping [/HttpUserService] to HandlerExecutionChain with handler [org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter@f9104a] and 1 interceptor 15.03.2012 21:26:41 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming HttpInvokerServiceExporter remote call: com.otv.http.server.IHttpUserService.deleteUser 15.03.2012 21:26:41 DEBUG (HttpUserService.java:45) - User has been deleted from cache. User : Id : 1, Name : Bruce, Surname : Willis 15.03.2012 21:26:41 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of HttpInvokerServiceExporter remote call: com.otv.http.server.IHttpUserService.deleteUser 15.03.2012 21:26:41 DEBUG (DispatcherServlet.java:957) - Null ModelAndView returned to DispatcherServlet with name 'HttpUserService': assuming HandlerAdapter completed request handling 15.03.2012 21:26:41 DEBUG (FrameworkServlet.java:913) - Successfully completed request ...
STEP 13 : DOWNLOAD
Reference: Spring Remoting Support with Http Invoker from our JCG partner Eren Avsarogullari at the Online Technology Vision blog.