![]() | ![]() | ![]() | ||||||||
![]() | ||||||||||
documentation examples changes overview quick start installation command-line configuration admin amber clustering caching database deployment ejb 3.0 embedding filters hessian hmtp ioc jsp logging messaging performance quercus/php remoting scheduled tasks security server push servlets third-party troubleshooting virtual hosting watchdog webapp xml and xslt | resin remoting
Resin's remoting lets applications write services as plain Java objects and export them with a choice of protocols, including Hessian, Burlap, CXF (SOAP), XFire. Because Resin activates the service as an IoC singleton, the service can use any of Resin's IoC capabilities, including dependency injection, AOP interception, EJB transactions, and event handling. For applications which need to use a custom protocol, making a new driver for a protocol is also straightforward. The Hello, World example shows the primary steps involved in creating a Resin remoting service:
API - defining the protocolDefining the protocol cleanly and clearly is the most critical aspect of designing a remote service. Because you will be sharing the protocol API among many other developers using different languages, it's critical to create a good design. The API classes are used for both the client and the server, ensuring compatibility. Even when the clients are expected to be written in a different language, e.g. Flash, C# or JavaScript, the API serves both as documentation and validation of the protocol. In the case of C#, the API can be translated automatically using reflection for strict compile-time validation. In this example, the API is easy. It's just a single method
call Example: Hello.java - API package qa; public interface Hello { public String hello(); } Service - implementing the serviceThe service implementation is a plain Java object that can optionally use Resin-IoC capabilities for dependency injection. The service is multithreaded, so it's the service-developer's responsibility to handle any synchronization or transaction issues, just like writing a servlet. In this example, the implementation is trivial, just returning the "hello, world" string. More complicated services might delegate to WebBeans or EJB services. Example: MyService.java - Service package qa; public class MyService implements Hello { public String hello() { return "hello, world"; } } Configuration - exporting the protocolWeb-based remoting protocols are exported using the HTTP protocol with well-known URLs; they're essentially fancy servlets. Resin lets you configure your services just like a servlet. The only additional configuration necessary is choosing the protocol. Protocol drivers like Hessian or CXF register the protocol implementation with a URI scheme like "hessian:" or "cxf:". Your service configuration will just select the appropriate protocol in a <protocol> configuration tag. In the example, we'll use Hessian, since it's a fast binary protocol with several language implementations. If you want to export multiple protocol bindings, you can just add new <servlet-mapping> definitions. Example: WEB-INF/resin-web.xml - Hessian Service <web-app xmlns="http://caucho.com/ns/resin"> <servlet-mapping url-pattern="/hello" servlet-class="qa.MyService"> <protocol uri="hessian:"/> </servlet-mapping> </web-app> We can easily change the protocol to use CXF instead of Hessian by changing the scheme from "hessian:" to "cxf:". Example: WEB-INF/resin-web.xml - CXF Service <web-app xmlns="http://caucho.com/ns/resin"> <servlet-mapping url-pattern="/hello" servlet-class="qa.MyService"> <protocol uri="cxf:"/> </servlet-mapping> </web-app> Client servlet - using the protocolOn the client side, the application needs a proxy to invoke the server methods. Since the protocols themselves are generic, the client will work with any server even if written in a different language like C#, as long as the protocol is compatible. The client uses Resin's dependency injection to get a client proxy for the protocol. By using dependency injection, the client code remains independent of the protocol choice or any protocol-setup housekeeping. The only dependency is on the client API itself. Because the client uses the type-safe API, the Java compiler validates the protocol, making compatibility as certain as possible. The Example: qa/MyServlet.java - Servlet Client package qa; import java.io.*; import javax.servlet.*; import javax.webbeans.*; public class MyServlet extends GenericServlet { @In private Hello _hello; public void service(ServletRequest request, ServletResponse response) throws IOException { out.println("hello: " + _hello.hello()); } } Although most clients will just have a single Configuration - selecting the protocolTo configure the client, you need to specify the protocol
type, the URL, and the API class in a
The example uses Hessian, so the Example: WEB-INF/resin-web.xml - Hessian Client <web-app xmlns="http://caucho.com/ns/resin"> <remote-client class="qa.Hello" uri="hessian:url=http://localhost:8080/hello"/> <servlet-mapping url-pattern="/demo" servlet-class="qa.MyServlet"/> </web-app> Since the client code only depends on the proxy API, changing to use CXF (SOAP) just requires changing the protocol scheme from "hessian:" to "cxf:". Example: WEB-INF/resin-web.xml - CXF Client <web-app xmlns="http://caucho.com/ns/resin"> <remote-client class="qa.Hello" uri="cxf:url=http://localhost:8080/hello"/> <servlet-mapping url-pattern="/demo" servlet-class="qa.MyServlet"/> </web-app> Resin 3.1.5 has the following protocol drivers available:
You can extend Resin's remoting protocols by adding a plugin for either the server or client. In either case, the required API is deliberately kept simple. Server pluginscom.caucho.remote.server.ProtocolServletFactory public interface ProtocolServletFactory { public Servlet createServlet(Class serviceClass, Object service) throws ServiceException; } Example: HessianProtocolServletFactory package com.caucho.remote.hessian; import com.caucho.hessian.server.*; import com.caucho.remote.*; import com.caucho.remote.server.*; import javax.servlet.*; public class HessianProtocolServletFactory extends AbstractProtocolServletFactory { public Servlet createServlet(Class serviceClass, Object service) throws ServiceException { HessianServlet servlet = new HessianServlet(); servlet.setHome(service); servlet.setHomeAPI(getRemoteAPI(serviceClass)); return servlet; } } Resin's URI aliases are configured by property files in
com.caucho.remote.server.ProtocolServletFactory burlap=com.caucho.remote.burlap.BurlapProtocolServletFactory hessian=com.caucho.remote.hessian.HessianProtocolServletFactory Client pluginscom.caucho.remote.client.ProtocolProxyFactory public interface ProtocolProxyFactory { public Object createProxy(Class api); } Example: HessianProtocolProxyFactory.java package com.caucho.remote.hessian; import com.caucho.hessian.client.*; import com.caucho.remote.*; import com.caucho.remote.client.*; public class HessianProtocolProxyFactory extends AbstractProtocolProxyFactory { private HessianProxyFactory _factory = new HessianProxyFactory(); private String _url; public void setURL(String url) { _url = url; } public Object createProxy(Class api) { try { return _factory.create(api, _url); } catch (Exception e) { throw ServiceException(e); } } }
|