Enterprise Java

Spring Remoting Support with Http Invoker

Spring HTTP Invoker is an important solution for Java-to-Java Remoting. This technology uses the standard Java serialization mechanism to expose services through HTTP and can be thought as an alternative solution instead of the custom serialization found in Hessian and Burlap. Also, it is only provided by Spring so both client and server applications have to be based on Spring.

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

OTV_SpringHttpInvoker

Reference: Spring Remoting Support with Http Invoker from our JCG partner Eren Avsarogullari at the Online Technology Vision blog.

Subscribe
Notify of
guest

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

0 Comments
Inline Feedbacks
View all comments
Back to top button