📄 resin-remoting.xtp
字号:
<document><header> <product>resin</product> <title>Resin Remoting</title> <description><p>Resin's remoting lets applications write services as plain Javaobjects and export them with a choice of protocols, includingHessian, Burlap, CXF (SOAP), XFire. Because Resin activatesthe service as an IoC singleton, the service can use any of<a href="resin-ioc.xtp">Resin's IoC capabilities</a>,including dependency injection, AOP interception, EJB transactions,and event handling.</p><p>For applications which need to use a custom protocol, making a newdriver for a protocol is also straightforward.</p> </description></header><body><localtoc/><s1 title="Example: Hello, World"><p>The Hello, World example shows the primary steps involved increating a Resin remoting service:</p><ol><li>Creating the public API</li><li>Creating the Java implementation</li><li>Configuring the service in the resin-web.xml and choosing the protocol</li><li>Configuring and using the client</li></ol><s2 title="API - defining the protocol"><p>Defining the protocol cleanly and clearly is the most criticalaspect of designing a remote service. Because you will besharing the protocol API among many other developers using differentlanguages, it's critical to create a good design.</p><p>The API classes are used for both the client and the server,ensuring compatibility. Even when the clients are expected to bewritten in a different language, e.g. Flash, C# or JavaScript, theAPI serves both as documentation and validation of the protocol.In the case of C#, the API can be translated automatically usingreflection for strict compile-time validation.</p><p>In this example, the API is easy. It's just a single methodcall <code>hello</code> returning a greeting string.</p><example title="Example: Hello.java - API">package qa;public interface Hello { public String hello();}</example></s2><s2 title="Service - implementing the service"><p>The service implementation is a plain Java object thatcan optionally use Resin-IoC capabilities for dependency injection.The service is multithreaded, so it's the service-developer'sresponsibility to handle any synchronization or transaction issues,just like writing a servlet.</p><p>In this example, the implementation is trivial, just returningthe "hello, world" string. More complicated services mightdelegate to WebBeans or EJB services.</p><example title="Example: MyService.java - Service">package qa;public class MyService implements Hello { public String hello() { return "hello, world"; }}</example></s2><s2 title="Configuration - exporting the protocol"><p>Web-based remoting protocols are exported using theHTTP protocol with well-known URLs; they're essentially fancyservlets. Resin lets you configure your services justlike a servlet. The only additional configuration necessaryis choosing the protocol.</p><p>Protocol drivers like Hessian or CXF register theprotocol implementation with a URI schemelike "hessian:" or "cxf:". Your service configuration willjust select the appropriate protocol in a <protocol>configuration tag.</p><p>In the example, we'll use Hessian, since it's a fast binaryprotocol with several language implementations. If you wantto export multiple protocol bindings, you can just add new<servlet-mapping> definitions.</p><example title="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></example><p>We can easily change the protocol to use CXF instead ofHessian by changing the scheme from "hessian:" to "cxf:".</p><example title="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></example></s2><s2 title="Client servlet - using the protocol"><p>On the client side, the application needs a proxy toinvoke the server methods. Since the protocols themselves aregeneric, the client will work with any server even if writtenin a different language like C#, as long as the protocol iscompatible.</p><p>The client uses Resin's dependency injection to get a client proxyfor the protocol. By using dependency injection, the client coderemains independent of the protocol choice or any protocol-setuphousekeeping. The only dependency is on the client API itself.Because the client uses the type-safe API, the Java compilervalidates the protocol, making compatibility as certain aspossible.</p><p>The <code>@javax.webbeans.In</code> annotation asks Resin tolookup the <code>qa.Hello</code> client stub that's been configuredand gives it to the servlet. Since the client stub is thread-safeit can be safely used in the servlet code.</p><example title="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()); }}</example><p>Although most clients will just have a single <code>Hello</code>proxy and can use the <code>@In</code> tag, more complicatedapplications can use the <code>@Named</code> tag or even custom<code>@BindingTag</code> annotations to select the right proxy.The <a href="resin-ioc.xtp">Resin IoC</a> documentation has moredetails.</p></s2><s2 title="Configuration - selecting the protocol"><p>To configure the client, you need to specify the protocoltype, the URL, and the API class in a<code><remote-client></code> tag in the resin-web.xml.Since the client code uses injection to get the proxy, we can switchprotocols if necessary.</p><p>The example uses Hessian, so the <code>uri</code> attributeuses a "hessian:" scheme with Hessian's <code>url</code>parameter. The API class is <code>qa.Hello</code>.</p><example title="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></example><p>Since the client code only depends on the proxy API, changingto use CXF (SOAP) just requires changing the protocol schemefrom "hessian:" to "cxf:".</p><example title="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></example></s2></s1><s1 title="Available Protocols"><p>Resin 3.1.5 has the following protocol drivers available:</p><ul><li>hessian: The <a href="http://hessian.caucho.com">Hessian</a>protocol is a fast, compact binary protocol with implementationsavailable in a large number of languages including Flash, PHPand C#.</li><li>burlap: The <a href="http://hessian.caucho.com">Burlap</a>protocol is the XML-based cousin of Hessian.</li><li>cxf: The <a href="http://wiki.caucho.com/CXF">CXF</a> driveruses the Apache CXF project for SOAP client and server protocols.</li></ul></s1><s1 title="Protocol Plugin Architecture"><p>You can extend Resin's remoting protocols by adding a plugin foreither the server or client. In either case, the required API isdeliberately kept simple.</p><s2 title="Server plugins"><def title="com.caucho.remote.server.ProtocolServletFactory">public interface ProtocolServletFactory { public Servlet createServlet(Class serviceClass, Object service) throws ServiceException;}</def><example title="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; }}</example><p>Resin's URI aliases are configured by property files in<code>WEB-INF/services/com.caucho.config.uri</code>. Each interfacehas its property file specifying the implementation class for eachURI scheme. In this case, the interfaceis <code>com.caucho.remote.server.ProtocolServletFactory</code>, so itthe scheme mappings are added to a file with the same name:</p><example title="com.caucho.remote.server.ProtocolServletFactory">burlap=com.caucho.remote.burlap.BurlapProtocolServletFactoryhessian=com.caucho.remote.hessian.HessianProtocolServletFactory</example></s2><s2 title="Client plugins"><def title="com.caucho.remote.client.ProtocolProxyFactory">public interface ProtocolProxyFactory{ public Object createProxy(Class api);}</def><example title="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); } }}</example></s2></s1></body></document>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -