Samstag, 18. September 2010

Simple RPC over HTTP using Hessian

From time to time i am asked to recommend a mechanism for a simple and lightweight RPC over HTTP(S) communication that for example could easily be integrated into a Rich Client or Mobile Client and that could pass firewalls.

Well, here's a short guide to get started with Hessian. The Hessian binary web service protocol makes web services usable without requiring a large framework. As it is a binary protocol, it is well-suited for sending binary data without any need to extend the protocol with attachments.

More info can be found here.

I would like to provide you here with a simple 3 step by step tutorial to get started using it. It is really that simple!

1. We start from the service interface and the corresponding implementation that will run on the remote server (all in package de.arconsis.wstest)

public interface IBusinessService { 
    public int myBusinessMethod(String param1, String param2);
}

public class BusinessServiceImpl implements IBusinessService {
    public int myBusinessMethod(String param1, String param2) {
        System.out.println("BS: " + param2 + param2);
        return param2.length() + param2.length();
    }
}

2. We put the compiled .class files into a WAR file under WEB-INF/classes or as a jar in the WEB-INF/lib as well as the hessian-3.1.2.jar and add the following entries to the web.xml and finally deploy the WAR.
<servlet>
        <servlet-name>hessian</servlet-name>
        <servlet-class>
            com.caucho.hessian.server.HessianServlet
        </servlet-class>
        <init-param>
            <param-name>home-class</param-name>
            <param-value>
                de.arconsis.wstest.BusinessServiceImpl
            </param-value>
        </init-param>
        <init-param>
            <param-name>home-api</param-name>
            <param-value>
                de.arconsis.wstest.IBusinessService
            </param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <url-pattern>/hessian</url-pattern>
        <servlet-name>hessian</servlet-name>
    </servlet-mapping>


3. Now we just need to call that remote service over HTTP from a client. Let's assume that the webserver with the Hessian Servlet is running on the localhost:8080. Make sure that the hessian-3.1.2.jar as well as the IBusinessService interface is also available in the classpath of the client. To make the remote call transparent it might be a good idea to hide the remote nature by using just the business service interface in the client that will be obtained by a factory.
package de.arconsis.wstest;

public class BusinessServiceFactory {
    private static BusinessServiceFactory self;


    private BusinessServiceFactory() {
    }

    public static BusinessServiceFactory getInstance() {
        if (self == null) {
            self = new BusinessServiceFactory();
        }
        return self;
    }


    public IBusinessService getBusinessService() {
        //return new BusinessServiceImpl();
        return new BusinessServiceRemoteImpl(); 
    }
} 



import com.caucho.hessian.client.HessianProxyFactory;

public class BusinessServiceRemoteImpl implements IBusinessService {

    public int myBusinessMethod(String param1, String param2) {        
        String url = "http://localhost:8080/hessian";

        HessianProxyFactory factory = new HessianProxyFactory();
        IBusinessService remote = null;
        
        try {
            remote = (IBusinessService) factory.create(IBusinessService.class, url);
        } catch (Exception e) {
            e.printStackTrace();
        }        
        return remote.myBusinessMethod(param1, param1);
    }
}


Hessian will use a dynamic proxy internally and handle all the magic using HTTP as transfer protocol as well as the de-/serializing of the parameters and return objects.

I hope this short guide will help someone ... ;-)

~Wolfgang

Keine Kommentare:

Kommentar veröffentlichen