Home > Java - J2EE > EJB 3.1 and DynamicHessianServlet

EJB 3.1 and DynamicHessianServlet

Hessian is a binary web service protocol that makes web services usable without requiring a large framework, and without learning a new set of protocols.

Moreover, Hessian may not be the best performing but in any case much more efficient than XML-based protocols.
Hessian allows data exchange between programs in different programming languages ​​and there are in mutually compatible implementations for the following programming languages​​:

Java Flash/Flex Python Ruby
C++ .NET C# Objective C D
Erlang PHP

For more information about hessian, see http://hessian.caucho.com/

In his blog, Adam Bien has written a simple example about EJB 3.1 and Hessian :  EJB 3.1 + Hessian = (Almost) Perfect Binary Remoting

The problem with this issue, it was also mentioned in one of comments, it must be written for each session bean, a hessian servlet. The solution is DynamicHessianServlet that dynamically invokes the required bean/method.

Here I have a simple example about DynamicHessianServlet. First I write a stateless EJB for business logic ;

@Stateless(name="ICustomerEjb")
public class CustomerEjb implements ICustomerEjb {

    @PersistenceContext
    private EntityManager entityManager;

    public CustomerService() { }

    public void persist(Customer entity) {
      entityManager.persist(entity);
    }

    public Customer update(Customer entity) {
      return entityManager.merge(entity);
    }
    // ... more Code
}

@Remote
public interface ICustomerEjb {

    void persist(Customer entity);

    Customer update(Customer entity);

    // ... more Code
}

and now DynamicHessianServlet that looks appropriate EJB in JNDI and dynamically invokes the required method in EJB.

@WebServlet(name = "DynamicHessianServlet", urlPatterns = {"/dynamic/*"})
public class DynamicHessianServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    private HessianSkeleton homeSkeleton;
    private SerializerFactory serializerFactory;

    public DynamicHessianServlet() { }

    public String getServletInfo() {
        return "Dynamic Hessian Servlet";
    }

    public SerializerFactory getSerializerFactory() {
        if (serializerFactory == null) {
            serializerFactory = new SerializerFactory();
        }
        return serializerFactory;
    }

    public void setSendCollectionType(boolean sendType) {
        getSerializerFactory().setSendCollectionType(sendType);
    }

    private Class loadClass(String className) throws ClassNotFoundException {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        if (loader != null) {
            return Class.forName(className, false, loader);
        } else {
            return Class.forName(className);
        }
    }

    public void service(ServletRequest request, ServletResponse response)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        if (!req.getMethod().equals("POST")) {
            res.sendError(500, "Hessian Requires POST");
            PrintWriter out = res.getWriter();
            res.setContentType("text/html");
            out.println("<h1>Hessian Requires POST</h1>");
            return;
        }

        String serviceId = req.getPathInfo().substring(1);        
        String objectId = req.getParameter("id");
        if (objectId == null) {
            objectId = req.getParameter("ejbid");
        }

        ServiceContext.begin(req, serviceId, objectId);
        try {
            InputStream is = request.getInputStream();
            OutputStream os = response.getOutputStream();

            response.setContentType("application/x-hessian");
            SerializerFactory serializerFactory = getSerializerFactory();

            Class clazz = loadClass(serviceId);
            InitialContext ctx = new InitialContext();    
            // complete lookup-String for GlassFish :
            // "java:global/myWebApp/com.domain.ICustomerEjb"       
            Object service = ctx.lookup("java:global/myWebApp/" + serviceId);

            homeSkeleton = new HessianSkeleton(service, clazz);
            homeSkeleton.invoke(is, os, serializerFactory);

        } catch (RuntimeException e) {
            throw e;
        } catch (ServletException e) {
            throw e;
        } catch (Throwable e) {
            throw new ServletException(e);
        } finally {
            ServiceContext.end();
        }
    }
}

The service is ready and needs no configuration in xml-file. Now I write a simple client that accesses this service.

HessianProxyFactory factory = new HessianProxyFactory();
// serviceId = com.domain.ICustomerEjb
String url = "http://localhost:8080/myWebApp/dynamic/com.domain.ICustomerEjb";

ICustomerEjb ejbService;
try {
   ejbService=(ICustomerEjb)factory.create(ICustomerEjb.class,url);

   Customer customer = new Customer("Test","Test");
   ejbService.persist(customer);
} catch (MalformedURLException e) {
   e.printStackTrace();
}

I hope it is useful for you.

Advertisements
  1. Darlene
    10. October 2011 at 11:40

    Thanks for the share! Very useful info.

  1. No trackbacks yet.

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s

%d bloggers like this: