Remote access with Spring HttpInvoker
Introduction
I can remember the early days of Java where I used RMI to create distributed system. But it is very difficult to use RMI these days because distributed communication is restricted due to the security concerns under the organizational policies. Enterprise applications are evolved to adapt to current environment but for small scale distributed systems are not possible. This fact mainly forced me to explore the new technologies which is best suit for my requirements which are listed below
- Enterprise applications are mainly depends on HTTP protocols. Therefore, my choice also HTTP. The RMI communication protocol is JRMP, but over the network, there are lot of problems communicating via JRMP. The best use is pure HTTP protocol without any tunneling because which can cause to firewall problems.
- The Framework should support to send and receive Java serialized objects over the chosen protocols (which is HTTP according to the above point).
- The development environment should be supported for RAD based IDE such as Eclipse Galileo.
I had few options like Hessian and Burlap. But these technologies are proprietary although they work well across firewalls. The Http invoker is the winner. The Http invoker is part of the Spring framework.
Note: Hessian and Burlap use proprietary serialization mechanisms which is portable to integrate with other technologies such as PHP and .NET. But Http Invoker support only Java serialization, this is the main disadvantage of using Http Invoker because its limited to use in the Java territories. |
Design
- SOSWeb is the web project which should be available in the Servlet container (in this example Servlet container is Apache Tomcat 6).
- SOSClient is the client application which is spring based Java application.
- SOSShared is the application which keeps shared items by both the above application. The main purpose of this application to avoid duplicate declarations.
I try to make the things simple as much as possible. In this class diagram, transfer objects and service interfaces are kept in the SOSShared subsystem because they are shared among Web and Client applications. For example, Child is a transfer object and HelloService is service interface which are available in the SOSShared subsystem. But service implementation is available in the SOSWeb subsystem and HelloClient in the SOSClient subsystem.
The objective of this hello world application is very simple to keep thing understandable. As shown in the above sequence diagram, frist HelloClient from the client side, send the request to HelloService via Http Invoker. In this request, newly created child will be sent to the SOSWeb subsystem, at the server side, this object will be save by the HelloServiceImpl. In the next, Client request, HelloClient requests the getHello() method from the HelloService, in return Http Invoker will execute th HelloServiceImpl and send bank the Child object to client side.
Implementation
Let’s go through the configuration first. Client side configration for HelloClient is as shown in the below code snippet.
................ ................... ... http://localhost:8080/SOSWeb/hello.service org.sos.ss.hello.HelloService
As shown in the above xml code, org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
is the proxy which will serialize the parameters and pass those serialized objects to the server side. The ugly code of “serviceUrl” can be replace by the place holder such as http://${serverName}/${contextPath}/hello.service, in which variable should be replaced by the property values. In this example, I will keep the above naked source to keep thing simple again.
The “serviceInterface” which should share the class from the SOSShare subsystem as explained above. In eclipse, you can make available by right click and selecting the “Build Path ->Configure Build Path” as shown in the following figure;
In the Properties for SOSClient add the SOSShared by click and selecting it. Let’ go through the client source which is very typical Spring client, nothing to explain.
package org.sos.ss.client.hello; import org.sos.ss.hello.HelloService; import org.sos.ss.to.child.Child; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloClient { /** * @param args */ public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml"); HelloService hello = (HelloService)ctx.getBean("helloservice"); Child child = new Child(); hello.setHello(child); Child c = hello.getHello(); System.out.println("Name "+ c.getName()+ " Age: "+ c.getAge()); } }
As shown in the above code, first we create child and send it to the server by calling setHello() as depicted in the sequence diagram. The next server call is execution of getHello() that is 3rd step of the sequence diagram.
Next you have to deploy the HelloService in the server side. Eclipse Web dynamic project for Tomcat 6.0 is the project configuration for this example. There is configuration file hello-servlet.xml which is part of the Spring MVC framework. It should be named as hello-servlet.xml because “hello” is the value given for the servlet-mapping in the web.xml file given in the following code.
.............. ..................SOSWeb index.html index.htm index.jsp default.html default.htm default.jsp hello org.springframework.web.servlet.DispatcherServlet 1 ... ... hello *.service
In this example, Servlet mapping is "hello", therefore what ever the request received as <any name>.service should consult the hello handler configured in the hello-servlet.xml which is given in the following code snippet.
................. .................org.sos.ss.hello.HelloService ... ... httpHelloService
The hello-servlet.xml define the Service Interfaces and the Service implementations as shown in the following code.
... ...org.sos.ss.hello.HelloService ... ... httpHelloService
As shown in the above code, org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter handle the responsiblity of deserializtion of received objects, serialization of returns and method call translation as pure plain Java method calls. According to the above code, when request received as “hello.service”, that will be mapped to the httpHelloService using org.springframework.web.servlet.handler.SimpleUrlHandlerMapping. There can be number of mappings in the <props> although this example shows only one.
To thing works, you have to provide the SOSShared subsystem to the Apache Tomcat runtime as shown in the above figure, right click the application and select “Run As –> Run Configurations…”, then select the Tomcat runtime from the left hand side menu. You can add SOSShared to the “User Entries”.
The HelloServiceImpl is simple as following code snippet.
package org.sos.ss.hello; import org.sos.ss.to.child.Child; public class HelloServiceImpl implements HelloService { Child child; int i; @Override public Child getHello() { changeChild(); return child; } @Override public void setHello(Child child) { this.child=child; } public void changeChild(){ child.setName("Ojitha"); child.setAge(i++); } }
Now everything is ready to run, first you have to deploy SOSWeb to the Tomcat web server, and run the SOSClient as a typical Java application. In the output, for each execution of client application, age will be increased by one as shown in the above code.
The working source code of this example can be downloaded.
Comments
Post a Comment
commented your blog