在商谈需求的过程中客户非常期待很快的能看到产品的原型,这样可以对他们公司高层进行演示,促进2个公司项目合作的进展。如果在开发的过程中采用实际系统架构中技术去实现不太实际,所以我想到了一个简单的方式来满足客户的要求,采用 Apache的XML-RPC 对多个模块之间通讯,并且不需要自己去定义XML协议,也无需定义无序的URL参数传递,因为这一切都由 Apache的XML-RPC中现成的xml传输协议实现了。虽然采用Apache XML-RPC的方式实现整个功能比较简单,但在原型中可以满足我们和客户想要达到的效果。
说白了XML-RPC其实就是一个通过xml协议实现的远程方法调用,XML-RPC的全称是XML Remote Procedure Call,在我看来是一个非常简单的WebService的实现,只要在服务端自己写一个类,构造一个方法,实现自己需要的业务逻辑,再通过一个配置文件指明其中映射的关系,例如:配置文件中的Calculator=com.demo.xmlrpc.DataHandler描述,客户端指明在服务端配置文件需要调用的对象名称和方法名称即可进行数据传输和通讯了,这种远程过程调用使用http作为传输协议,XML作为传送信息的编码格式。Xml-RPC的定义尽可能的保持了简单,但同时能够传送、处理、返回复杂的数据结构。原理如图1所示:
服务端代码示例:
WebServer webServer = new WebServer(8080);
XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
PropertyHandlerMapping phm = new PropertyHandlerMapping();
phm.load(Thread.currentThread().getContextClassLoader(), "DataHandlers.properties");
客户端代码示例:
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://127.0.0.1:8080"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
List<String> list = new ArrayList<String> ();
list.add( "data1" );list.add( "data2" );list.add( "data3" );
Object result = client.execute("Calculator.getRequestData", new Object[]{list } );
业务逻辑代码示例:
public int getRequestData( List<String> list){
System.out.println("\nServer Side print:");
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
return list.size();
}
配置文件示例:
Calculator=com.demo.xmlrpc.DataHandler
运行程序:
1.运行服务端,启动的默认端口为8080,
2.客户端通过代码中的 client.execute(……)方法,传入 ("映射名称.方法名称",入参数据)即可。
3.服务端会打印出通过业务逻辑代码循环出的一组数据,客户端会显示出传入参数的个数。
效果如图2所示:
XML-RPC与Web容器集成
可以将XML-RPC的服务端写成Servlet集成在Tomcat或者Jetty中, 将并发和会话等资源相关的问题,交给web容器去处理,因为XML-RPC中启动的web Server毕竟是一个嵌入式的,只能处理非大量的请求。 在服务端还是2个程序1个配置文件:1.继承XmlRpcServlet (extends XmlRpcServlet) 写一个servlet,2.业务逻辑程序。3.创建一个配置文件跟上面的方法一样。
此时,在XML-RPC与Web容器集成的环境中web工程下的web.xml文件扮演了重要的角色。 xml-rpc中的web.xml示例: 在web.xml文件中需要定义了这些内容:
<servlet> <servlet-name>XmlRpcServlet</servlet-name> <servlet-class>com.javabloger.demo.xmlrpc.RpcServer</servlet-class> <init-param> <param-name>enabledForExtensions</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>configFile</param-name> <param-value>DataHandlers.properties</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>XmlRpcServlet</servlet-name> <url-pattern>/xmlrpc</url-pattern> </servlet-mapping>
1.服务端的servlet
2.xml-rpc中的配置文件
3.url的站点路径。
XLM-RPC的数据类型
只能支持Java中最基本的一些基本类型,例如:Integer、String、Double 等,详见:http://ws.apache.org/xmlrpc/types.html
扩展话题
rpc-xml不支持对象的传递,只支持String、List、Map 等一些Java中基本的数据类型,如果要传递自定义的对象(POJO)可以将这组对象转化成XML格式用Stringbuffer拼装起来,服务端再将传入的字符型xml字符串解析成一个或者一组对象,结合 Xstream开源框架完成一个对XML-RPC自定义对象(POJO)传递的扩展应用。另外在XML-RPC的客户端中还可以设置对http server的用户名和秘密验证以及gzip压缩和编码的定义,例如:basicUserName,basicPassword、basicEncoding,gzipCompressing 等。
文中代码示例下载
http://javabloger-mini-books.googlecode.com/files/xml-rpc.zip