一、XML-RPC介绍
按照XML-RPC的规范,定义是:XML-RPC是工作在互联网上的远程程序调用协议。
它可以允许软件运行在分布式的系统之上,通过互联网进行软件中程序之间的调用。
其传输协议是HTTP,传送数据编码格式是XML。由于是通过HTTP传输数据,因此基于XML-RPC的软件不受操作环境环境、
编程语言等限制( 比如RMI只能用于java程序之间传输),由于是通过http协议传输,因此可以通过防火墙的限制,具有简单易用等特点。
二,下载XML-RPCkuangjia
XML-RPC只是一个协议,这里主要介绍一个实现了 XML-RPC 协议的 java 开源的框架apache的 XML-RPC 实现。
XML-RPC框架的下载地址是:http://ws.apache.org/xmlrpc/download.html
※当前该页面的下载链接全部失效了.最新的下载地址为http://archive.apache.org/dist/ws/xmlrpc/,下载apache-xmlrpc-current-bin.zip后,将lib下面的jar解压到工程目录中.
三、创建XML-RPC服务器端。
创建XmlRpcServer服务器端主要有两种方式:
1)直接将框架中的类 org.apache.xmlrpc.webserver.XmlRpcServlet 嵌入到Servlet容器中。
框架提供了一个Servlet的实现类: org.apache.xmlrpc.webserver.XmlRpcServlet,
这个类自动的嵌入了 XmlRpcServer中,因此只需要将这个类部署到 Servlet容器中即可实现服务端。具体步骤是:
a.创建一个Dynamic Web Project工程,配置web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>XML_RPC_Server</display-name>
<description>XMl_RPC_Server Appliction</description>
<servlet>
<servlet-name>XmlRpcServlet</servlet-name>
<servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class>
<init-param>
<param-name>enabledForExtensions</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>XmlRpcServlet</servlet-name>
<url-pattern>/service</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
※XmlRpcServlet有两个重要的配置属性:
・enabledForExceptions:当服务端捕获到一个异常时,并且在web.xml文件中配置了这个属性为true,服务端会将这个异常转换成一个字节数组Byte[]返回给客户端。
・enabledForExtensions:这个开源框架设置这个属性是为了扩展 XML-RPC协议的,因为完全符合原始协议 会有许多功能上的限制,比如一些基本的java原始数据类型都不能用,并且还要求发送的请求(request)需要设置content-length头,在http协议中,在请求头文件中设置这个属性意味着在发送请求或者相应之前,要把请求或者相应强制的写到字节数组中,而这是很耗时耗内存的工作。默认的情况下,是符合原始的XML-RPC协议的,也即这个属性值是false的,我们可以设置这个属性为true来扩展协议,需要注意的是 ,在client端与server端都有这个属性,只有在两端同时设置这个属性为true时才可用。设置这个属性后,就可以使用非常快速的节省内存的流模式,并且允许大部分的java对象传输:long, short, byte,float, DOM 节点, 实现了java.io.Serializable接口的对象实例 或者 JAXB对象。
b. 创建一个名称为XmlRpcServlet.properties的属性文件,里面用来存放处理远程调用的类,内容是
Calculator=service.Calculator,
这里名字可以任意取,主要是用来在服务端注册这个实例类的。
※注意:这个属性文件的名称和存储的包名是固定的,并且必须放在 org.apache.xmlrpc.webserver 这个包下面.
c.定义处理远程调用的类
package service;
public class Calculator {
public int add(int i1, int i2) {
return i1 + i2;
}
public int subtract(int i1, int i2) {
return i1 - i2;
}
}
2)利用XML-RPC自带的Http Server实现服务器端
利用WebServer作为服务端是经常用的方式,利用这种方式,需要手动的去读取配置文件,但是这里可以任意的命名属性配置文件,当然也可以在程序中指定属性。
但是相对于嵌入到Servlet的方式,这种方式要慢一些。代码如下:
package webserver;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;
public class Server {
private static final int port = 8080;
public static void main(String[] args) throws Exception {
WebServer webServer = new WebServer(port);
XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
PropertyHandlerMapping phm = new PropertyHandlerMapping();
/* 从配置文件中加载.
* The property file might look like:
* Calculator=org.apache.xmlrpc.demo.Calculator
* org.apache.xmlrpc.demo.proxy.Adder=org.apache.xmlrpc.demo.proxy.AdderImpl
*/
phm.load(Thread.currentThread().getContextClassLoader(), "MyHandlers.properties");
/* 也可以像这样直接指定:
* phm.addHandler("Calculator", org.apache.xmlrpc.demo.Calculator.class);
* phm.addHandler(org.apache.xmlrpc.demo.proxy.Adder.class.getName(), org.apache.xmlrpc.demo.proxy.AdderImpl.class);
*/
xmlRpcServer.setHandlerMapping(phm);
XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
serverConfig.setEnabledForExtensions(true);
serverConfig.setContentLengthOptional(false);
webServer.start();
}
}
在src目录下面MyHandlers.properties,文件内容为:Calculator=service.Calculator
这样服务器端就创建起来了。
三、创建XML-RPC客户端。
1)客户端主要是通过XmlRpcClient类来实现,这是一个无状态的线程安全的类,客户端的配置主要是通过这两个对象来配置:
a. ClientConfig 在这个接口类中设置一些原子属性,比如服务端rul、编码格式等,这个类的实现都是XmlRpcClientConfig的接口实现
b. TransportFactory 这个接口的任务是创建一个利用客户端的配置信息来与服务端对话的类,这里有两个这样的实现类,一个是创建 java.net里面的类(默认情况下是用这个)来与服务端进行通信,还有一个是利用Jakarta Commons Http Client的实现类
2)利用默认的TransportFactory的客户端代码片段
package xmlrpc.client;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
public class ClientTest {
public static void main(String[] args) {
try {
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://127.0.0.1:8080/XML_RPC_Server/service"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
Object[] params = new Object[] { new Integer(31), new Integer(9) };
Integer result = (Integer) client.execute("Calculator.add", params);
System.out.println(result);
result = (Integer) client.execute("Calculator.subtract", params);
System.out.println(result);
} catch (XmlRpcException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}