- 学习 XML-RPC
- XML-RPC - 首页
- XML-RPC - 简介
- XML-RPC - 数据模型
- XML-RPC - 请求
- XML-RPC - 响应
- XML-RPC - 错误
- XML-RPC - 示例
- XML-RPC - 总结
- XML-RPC 资源
- XML-RPC - 快速指南
- XML-RPC - 有用资源
XML-RPC - 快速指南
XML-RPC - 简介
RPC 代表远程过程调用。顾名思义,它是一种调用远程计算机上可用过程或函数的机制。RPC 是一种比 Web 更古老的技术。实际上,RPC 为开发人员提供了一种定义可在网络上调用的接口的机制。这些接口可以像单个函数调用一样简单,也可以像大型 API 一样复杂。
什么是 XML-RPC?
XML-RPC 是最简单和最可靠的 Web 服务方法之一,它使计算机能够轻松地调用其他计算机上的过程。
XML-RPC 允许程序跨网络进行函数或过程调用。
XML-RPC 使用 HTTP 协议将信息从客户端计算机传递到服务器计算机。
XML-RPC 使用一小部分 XML 词汇来描述请求和响应的性质。
XML-RPC 客户端在 XML 请求中指定过程名称和参数,服务器在 XML 响应中返回错误或响应。
XML-RPC 参数是类型和内容的简单列表 - 结构体和数组是可用的最复杂类型。
XML-RPC 没有对象的概念,也没有包含使用其他 XML 词汇的信息的机制。
但是,使用 XML-RPC 和 Web 服务,Web 成为过程连接的集合,计算机沿着紧密绑定的路径交换信息。
XML-RPC 诞生于 1998 年初;它由 UserLand Software 发布,并最初在其 Frontier 产品中实现。
为什么要使用 XML-RPC?
如果您需要集成多个计算环境,但不需要直接共享复杂的数据结构,您会发现 XML-RPC 使您能够快速轻松地建立通信。
即使您在一个环境中工作,您也可能会发现 RPC 方法使连接具有不同数据模型或处理期望的程序变得容易,并且它可以提供对可重用逻辑的轻松访问。
XML-RPC 是建立各种计算机之间连接的绝佳工具。
XML-RPC 为集成人员提供了一个使用标准词汇和方法交换信息的机会。
XML-RPC 最明显的应用领域是连接不同类型的环境,允许 Java 与 Perl、Python、ASP 等进行通信。
XML-RPC 技术概述
XML-RPC 由三个相对较小的部分组成
XML-RPC 数据模型:用于传递参数、返回值和错误(错误消息)的一组类型。
XML-RPC 请求结构:包含方法和参数信息的 HTTP POST 请求。
XML-RPC 响应结构:包含返回值或错误信息的 HTTP 响应。
我们将在接下来的三章中学习所有这三个组件。
XML-RPC - 数据模型
XML-RPC 规范定义了六种基本数据类型和两种复合数据类型,这些复合数据类型表示类型的组合。
XML-RPC 中的基本数据类型
类型 | 值 | 示例 |
---|---|---|
int 或 i4 | -2,147,483,648 到 2,147,483,647 之间的 32 位整数。 |
<int>27</int> <i4>27</i4> |
double | 64 位浮点数 |
<double>27.31415</double> <double>-1.1465</double> |
Boolean | true (1) 或 false (0) |
<boolean>1</boolean> <boolean>0</boolean> |
string | ASCII 文本,尽管许多实现支持 Unicode |
<string>Hello</string> <string>bonkers! @</string> |
dateTime.iso8601 | ISO8601 格式的日期:CCYYMMDDTHH:MM:SS |
<dateTime.iso8601> 20021125T02:20:04 </dateTime.iso8601> <dateTime.iso8601> 20020104T17:27:30 </dateTime.iso8601> |
base64 | 根据 RFC 2045 定义的 Base 64 编码的二进制信息 |
<base64>SGVsbG8sIFdvcmxkIQ==</base64> |
这些基本类型始终包含在value元素中。字符串(并且只有字符串)可以包含在value元素中,但省略string元素。这些基本类型可以组合成两种更复杂的类型,数组和结构体。数组表示顺序信息,而结构体表示名称-值对,类似于哈希表、关联数组或属性。
数组由array元素指示,该元素包含一个data元素,其中包含值的列表。与其他数据类型一样,array元素必须包含在value元素中。例如,以下array包含四个字符串
<value> <array> <data> <value><string>This </string></value> <value><string>is </string></value> <value><string>an </string></value> <value><string>array.</string></value> </data> </array> </value>
以下数组包含四个整数
<value> <array> <data> <value><int>7</int></value> <value><int>1247</int></value> <value><int>-91</int></value> <value><int>42</int></value> </data> </array> </value>
数组还可以包含不同类型的混合,如下所示
<value> <array> <data> <value><boolean>1</boolean></value> <value><string>Chaotic collection, eh?</string></value> <value><int>-91</int></value> <value><double>42.14159265</double></value> </data> </array> </value>
创建多维数组很简单 - 只需在数组中添加一个数组即可
<value> <array> <data> <value> <array> <data> <value><int>10</int></value> <value><int>20</int></value> <value><int>30</int></value> </data> </array> </value> <value> <array> <data> <value><int>15</int></value> <value><int>25</int></value> <value><int>35</int></value> </data> </array> </value> </data> </array> </value>
一个简单的结构体可能如下所示
<value> <struct> <member> <name>givenName</name> <value><string>Joseph</string></value> </member> <member> <name>familyName</name> <value><string>DiNardo</string></value> </member> <member> <name>age</name> <value><int>27</int></value> </member> </struct> </value>
这样您就可以实现几乎所有编程语言支持的数据类型。
XML-RPC - 请求格式
XML-RPC 请求是 XML 内容和 HTTP 标头的组合。XML 内容使用数据类型结构传递参数并包含识别正在调用的过程的其他信息,而 HTTP 标头提供用于通过 Web 传递请求的包装器。
每个请求都包含一个 XML 文档,其根元素是methodCall元素。每个methodCall元素都包含一个methodName元素和一个params元素。methodName元素标识要调用的过程的名称,而params元素包含参数及其值的列表。每个params元素都包含一个param元素列表,而param元素又包含value元素。
例如,要将请求传递给名为circleArea的方法,该方法采用Double参数(表示半径),则 XML-RPC 请求将如下所示
<?xml version="1.0"?> <methodCall> <methodName>circleArea</methodName> <params> <param> <value><double>2.41</double></value> </param> </params> </methodCall>
这些请求的 HTTP 标头将反映发送方和内容。基本模板如下所示
POST /target HTTP 1.0 User-Agent: Identifier Host: host.making.request Content-Type: text/xml Content-Length: length of request in bytes
例如,如果circleArea方法可从侦听于/xmlrpc的 XML-RPC 服务器获得,则请求可能如下所示
POST /xmlrpc HTTP 1.0 User-Agent: myXMLRPCClient/1.0 Host: 192.168.124.2 Content-Type: text/xml Content-Length: 169
组合在一起,整个请求将如下所示
POST /xmlrpc HTTP 1.0 User-Agent: myXMLRPCClient/1.0 Host: 192.168.124.2 Content-Type: text/xml Content-Length: 169 <?xml version="1.0"?> <methodCall> <methodName>circleArea</methodName> <params> <param> <value><double>2.41</double></value> </param> </params> </methodCall>
这是一个普通的 HTTP 请求,带有精心构造的有效负载。
XML-RPC - 响应格式
响应与请求非常相似,但有一些额外的变化。如果响应成功 - 找到过程、正确执行并返回结果 - 那么 XML-RPC 响应将与请求非常相似,除了methodCall元素被methodResponse元素替换,并且没有methodName元素
<?xml version="1.0"?> <methodResponse> <params> <param> <value><double>18.24668429131</double></value> </param> </params> </methodResponse>
XML-RPC 响应只能包含一个参数。
该参数可以是数组或结构体,因此可以返回多个值。
始终需要在响应中返回值。“成功值” - 也许是设置为 true (1) 的布尔值。
与请求一样,响应打包在 HTTP 中并具有 HTTP 标头。所有 XML-RPC 响应都使用 200 OK 响应代码,即使消息中包含错误也是如此。标头使用与请求类似的通用结构,并且典型的一组标头可能如下所示
HTTP/1.1 200 OK Date: Sat, 06 Oct 2001 23:20:04 GMT Server: Apache.1.3.12 (Unix) Connection: close Content-Type: text/xml Content-Length: 124
XML-RPC 只需要 HTTP 1.0 支持,但 HTTP 1.1 兼容。
Content-Type 必须设置为 text/xml。
Content-Length 标头指定响应的长度(以字节为单位)。
完整的响应,包括标头和响应有效负载,将如下所示
HTTP/1.1 200 OK Date: Sat, 06 Oct 2001 23:20:04 GMT Server: Apache.1.3.12 (Unix) Connection: close Content-Type: text/xml Content-Length: 124 <?xml version="1.0"?> <methodResponse> <params> <param> <value><double>18.24668429131</double></value> </param> </params> </methodResponse>
从 XML-RPC 服务器传递到 XML-RPC 客户端后,连接将关闭。后续请求需要作为单独的 XML-RPC 连接发送。
XML-RPC - 错误格式
XML-RPC 错误是一种响应类型。如果处理 XML-RPC 请求时出现问题,则methodResponse元素将包含fault元素而不是params元素。fault元素与params元素一样,只有一个值表示出现问题。错误响应可能如下所示
<?xml version="1.0"?> <methodResponse> <fault> <value><string>No such method!</string></value> </fault> </methodResponse>
错误也将具有错误代码。XML-RPC 根本不标准化错误代码。您需要检查特定软件包的文档以了解它们如何处理错误。
错误响应也可以如下所示
<?xml version="1.0"?> <methodResponse> <fault> <value> <struct> <member> <name>code</name> <value><int>26</int></value> </member> <member> <name>message</name> <value><string>No such method!</string></value> </member> </struct> </value> </fault> </methodResponse>
XML-RPC - 示例
为了演示 XML-RPC,我们将创建一个使用 Java 处理 XML-RPC 消息的服务器,并将创建一个 Java 客户端来调用该服务器上的过程。
对话的 Java 端使用 Apache XML 项目的 Apache XML-RPC,可从http://xml.apache.org/xmlrpc/获取
将所有 .jar 文件放在适当的路径中,让我们使用 JAVA 创建一个客户端和一个小型 XML-RPC 服务器。
XML-RPC 客户端
让我们编写一个 XML-RPC 客户端来调用名为sum函数的函数。此函数接受两个参数并返回它们的和。
import java.util.*; import org.apache.xmlrpc.*; public class JavaClient { public static void main (String [] args) { try { XmlRpcClient client = new XmlRpcClient("https://127.0.0.1/RPC2"); Vector params = new Vector(); params.addElement(new Integer(17)); params.addElement(new Integer(13)); Object result = server.execute("sample.sum", params); int sum = ((Integer) result).intValue(); System.out.println("The sum is: "+ sum); } catch (Exception exception) { System.err.println("JavaClient: " + exception); } } }
让我们看看上面示例客户端中发生了什么。
Java 包 org.apache.xmlrpc 包含 XML-RPC Java 客户端和 XML-RPC 服务器的类,例如 XmlRpcClient。
java.util 包对于 Vector 类是必需的。
函数server.execute(...)将请求发送到服务器。过程 sum(17,13) 在服务器上被调用,就像它是本地过程一样。过程调用的返回值始终是 Object。
这里“sample”表示在服务器中定义的处理程序。
请注意,过程调用的所有参数始终都收集在 Vector 中。
XmlRpcClient 类是通过指定服务器机器的“网络地址”后跟 /RPC2 来构造的。
localhost - 表示本地机器
您可以指定 IP 号码而不是 localhost,例如 194.80.215.219
您可以指定域名,例如 xyz.dyndns.org
您可以指定端口号以及域名,例如 xyz.dyndns.org:8080。默认端口为 80
请注意,远程过程调用的结果始终是 Object,并且必须将其强制转换为适当的类型。
当出现问题(无连接等)时,会抛出异常,并且必须使用catch语句捕获它。
由于上述调用,客户端向服务器发送以下消息。请注意,这是由server.execute(...)在内部处理的,您无需处理它。
<?xml version="1.0" encoding="ISO-8859-1"?> <methodCall> <methodName>sample.sum</methodName> <params> <param> <value><int>17</int></value> </param> <param> <value><int>13</int></value> </param> </params> </methodCall>
XML-RPC 服务器
以下是使用 Java 编写的 XML-RPC 服务器的源代码。它利用了org.apache.xmlrpc.*中可用的内置类。
import org.apache.xmlrpc.*; public class JavaServer { public Integer sum(int x, int y) { return new Integer(x+y); } public static void main (String [] args) { try { System.out.println("Attempting to start XML-RPC Server..."); WebServer server = new WebServer(80); server.addHandler("sample", new JavaServer()); server.start(); System.out.println("Started successfully."); System.out.println("Accepting requests. (Halt program to stop.)"); } catch (Exception exception) { System.err.println("JavaServer: " + exception); } } }
让我们看看我们在上面示例服务器中做了什么。
org.apache.xmlrpc 包包含用于 XML-RPC 服务器实现的 WebServer 类。
远程调用的过程sum在类中的公共方法中实现。
然后将同一服务器类的实例与客户端可访问的处理程序关联。
服务器由端口号(此处为:80)初始化。
当出现问题时,会抛出异常,并且必须使用catch语句捕获它。
对于给定示例客户端中提到的调用,服务器将以下响应发送回客户端
<?xml version="1.0" encoding="ISO-8859-1"?> <methodResponse> <params> <param> <value><int>30</int></value> </param> </params> </methodResponse>
现在您的服务器已准备就绪,因此请在提示符下编译并运行它,如下所示
C:\ora\xmlrpc\java>java JavaServer Attempting to start XML-RPC Server... Started successfully. Accepting requests. (Halt program to stop.)
现在要测试功能,请如下调用此服务器
C:\ora\xmlrpc\java>java JavaClient 30
XML-RPC - 总结
在本教程中,您学习了什么是 XML-RPC 以及为什么要使用 XML-RPC。我们讨论了它的数据模型,以及客户端和服务器之间交换的请求和响应消息格式。我们提供了一个示例来演示 XML-RPC 客户端和服务器如何交换信息。
XML-RPC是一个非常简单的概念,功能有限。从许多方面来说,这些限制是XML-RPC最吸引人的特性,因为它们大大降低了实现该协议和测试其互操作性的难度。
虽然XML-RPC很简单,但巧妙地运用简单的工具可以创建复杂而强大的架构。在需要各种不同系统进行通信的情况下,XML-RPC可能是最合适的最低公分母。
下一步是什么?
下一步是学习WSDL和SOAP。
WSDL
WSDL是一种基于XML的语言,用于描述Web服务以及如何访问它们。
WSDL描述了一个Web服务,以及Web服务的报文格式和协议细节。
如果您想了解更多关于WSDL的信息,请参阅我们的WSDL教程。
SOAP
SOAP是一个简单的基于XML的协议,允许应用程序通过HTTP交换信息。
如果您想了解更多关于SOAP的信息,请参阅我们的SOAP教程。