Showing posts with label http. Show all posts
Showing posts with label http. Show all posts

Monday, July 30, 2007

Spring HTTP Remoting - How ?

preface:
Spring give us few ways to communicate between client and server.
One of these ways is by using http remoting.
Http remoting is a way to invoke remote methods on server.
Spring http remoting uses Http protocol in order to achive that goal.

When do we need it?
When we want our server to expose services to clients.
say we want to expose service who gives us collection of some application users.

How we do it?
Server will expose service using simple independent interface:
public interface userService{
public Collection getAllUsers();
}

As you can see the interface can be independent, and no need to extend from nothing.

Then, we will implement this interface:
public class UserServiceImpl implements UserService{
public Collection getAllUsers() {
//do implementation...
}
}

Client - need to have only the interface in its class path.
Serevr - need to have both interface and implementing class in its classpath.

So, client is unknow with the implementation, only with the interface - like we wish for.

In order to make it work, we will use Spring HTTP Remoting.
Spring Http remoting uses the standard Java serialization mechanism to expose services through HTTP.

Exposing server service:
first, we will create simple bean using spring. the bean will be the service implementation:
< id="userService" class="example.UserServiceImpl">

then, we will expose the service with name "/UserService">
< name="">/UserService"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
< name="service" ref="userService">
< name="serviceInterface" value="example.UserService">
< /bean >

Configuration of web.xml (only once for all services):
< /servlet &gt
< servlet-name &gt remoting < / servlet-name &gt
< servlet-class &gt org.springframework.web.servlet.DispatcherServlet < / servlet-class &gt
< /servlet >

<>
remoting < / servlet-name >
/remoting/* < /url-pattern >
< /servlet-mapping >


Linking the service at the client side:
< id="">userServiceProxy"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean" >
< name="serviceUrl" value="">/UserService"/ >
< name="serviceInterface" value="">UserService"/ >
< /bean >

Then, in order to invoke service:
UserService service = (UserService) appContext.getBean("userServiceProxy");
Collection allUsers = service.getAllUsers();


And.. thats it. service will be invoked on server and client will get the results.

So, how it works ?


  1. The userServiceProxy bean that we created is a proxy.
  2. When method is being called, the proxy takes the method and its arguments and creates org.springframework.remoting.support.RemoteInvocation object. this object holds the information about the method invoked, like method name and which arguments given to method (and more).
  3. The RemoteInvocation object is serialiezed and pushed into an http request to url we declared in "serviceUrl" property of proxy ("http://host:8080/remoting/UserService").
  4. When request reachs server, the url is mapped by us in web.xml and will be dispatch to a spring servlet.
  5. The RemoteInvocation object is deserialized, and by using reflaction the method is being executed - on server.
  6. Then org.springframework.remoting.support.RemoteInvocationResult object will be created. this object will hold the result of execution or the exception if accured.
  7. The RemoteInvocationResult object will serialized and phushed into an HTTP response.
  8. Client will get the response, and will deserialize RemoteInvocationResult object.
  9. If the RemoteInvocationResult object holds an exception - it will be thrown, else the value of method will be returned.

So as you can see, using Spring http is very easy to use and to understand. spring give us a way to make remote invocation transparent for us, and we can use services as they were on our client.

This mechanism can be extended and give us more abilities, like adding attributes on request and so on... i hope i will find the time to represent these abilities in the near futher.