XML-RPC远程方法调用
一.简介
XML-RPC的全称是XML Remote Procedure Call,即XML远程方法调用。
它是一套允许运行在不同操作系统、不同环境的程序实现基于Internet过程调用的规范和一系列的实现。 这种远程过程调用使用http作为传输协议,XML作为传送信息的编码格式。 XML-RPC的定义尽可能的保持了简单,但同时能够传送、处理、返回复杂的数据结构。
XML-RPC的可用版本
XML-RPC client和XML-RPC server都有很多版本的实现。一般而言,一个实现版本都会同时实现client/server。但由于都满足xml rpc规范,从理论上讲,任何一个版本的XML-RPC client实现与任何一个版本的XML-RPC server都能配套使用。
更进一步,由于XML-RPC以XML文本的方式,使用http协议传输,所以与编程语言无关。例如:XML-RPC client的已实现版本包括了:perl,php,python,c/c++,java,等等;XML-RPC server的实现语言包括perl,java,等。
同一种编程语言所实现的版本也不止一个。例如java版的实现有:
Marque的XML-RPC现在已经和Redstone XML-RPC Library合并(http://xmlrpc.sourceforge.net/)
Apache的XML-RPC实现,这个项目隶属于apache web service项目,故URL地址开头为ws.apache(http://ws.apache.org/)下载链接http://archive.apache.org/dist/ws/有些时候直接点进项目去,无法通过镜像下载,这时候就可以访问http://archive.apache.org/通过这个链接可以下载apache的任何资源。话说apache真是伟大呀!
这个网页讲的真是太好了,虽然是英语:http://www.tutorialspoint.com/xml-rpc/xml_rpc_quick_guide.htm
这个网页讲的有点深:http://www.ibm.com/developerworks/cn/webservices/1211_zhusy_rpc/
二.python实现
牛人太多,我已无言。python实现http://blog.csdn.net/abcjennifer/article/details/38393185
创建服务器,构造方法,注册方法
from SimpleXMLRPCServer import SimpleXMLRPCServer
def is_even(n):
return n%2 == 0
server = SimpleXMLRPCServer(("localhost", 8000))#确定URL和端口
print "Listening on port 8000..."
server.register_function(is_even, "is_even") #注册is_even函数
server.serve_forever()#启动服务器,并使其对这个连接可用
创建客户端,请求方法
import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
print "3 is even: %s" % str(proxy.is_even(3))#客户端调用XML-RPC函数
print "100 is even: %s" % str(proxy.is_even(100))
三.xmlrpc++是C++版的xml-rpc接口实现
四.java大法好,一统天下
apache的XML-RPC似乎发生了很大改变,变得极为严谨。
下面的代码分为服务器端和客户端两部分,故意用了用一句话编程。读之给人一种一气呵成,气贯长虹质感。功能是:服务器端有两个函数add和sub,客户端请求其中之一并传入两个int类型的参数,返回int类型的结果并输出。
服务器端代码:
class RPCServer {
public static void main(String[] args) throws IOException {
WebServer server = new WebServer(8080);
server.getXmlRpcServer().setHandlerMapping(new XmlRpcHandlerMapping() {
@Override
public XmlRpcHandler getHandler(String handlerName)
throws XmlRpcNoSuchHandlerException, XmlRpcException {
switch (handlerName) {
case "add" :
return new XmlRpcHandler() {
@Override
public Object execute(XmlRpcRequest arg)
throws XmlRpcException {
int x = (int) arg.getParameter(0),
y = (int) arg.getParameter(1);
return x + y;
}
};
case "sub" :
return new XmlRpcHandler() {
@Override
public Object execute(XmlRpcRequest arg)
throws XmlRpcException {
int x = (int) arg.getParameter(0),
y = (int) arg.getParameter(1);
return x - y;
}
};
default :
return null;
}
}
});
server.start();
}
}
下面是客户端代码
class RPCClient {
public static void main(String[] args) throws XmlRpcException {
XmlRpcClient client = new XmlRpcClient();
int ans = (int) client.execute(new XmlRpcRequest() {
int x = 3, y = 6;
@Override
public int getParameterCount() {
return 2;
}
@Override
public Object getParameter(int x) {
if (x == 0)
return this.x;
else
return this.y;
}
@Override
public String getMethodName() {
return "add";
}
@Override
public XmlRpcRequestConfig getConfig() {
XmlRpcClientConfigImpl x = new XmlRpcClientConfigImpl();
try {
x.setServerURL(new URL("http://localhost:8080"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return x;
}
});
System.out.println(ans);
}
}
五.关于metaweblog协议
这个协议应用了XML-RPC,是各大博客统一支持的接口,供用户使用。百度metaweblog会出来一堆的,用这几个函数接口就足以访问博客了。下面以博客园的接口为例简要介绍:
三个大类九大函数七大结构体:
三个大类是谁?blogger(2个函数),metaWeblog(6个函数),wp(1个函数)
九大函数是谁?
•blogger.deletePost 删除随笔
•blogger.getUsersBlogs获取我的博客,我可能有多个博客
•metaWeblog.editPost修改随笔
•metaWeblog.getCategories获取随笔类别
•metaWeblog.getPost获取随笔
•metaWeblog.getRecentPosts获取最近随笔
•metaWeblog.newMediaObject新建多媒体对象,其实就是上传文件,在博客园里面只能上传图片,返回图片的url,这样这文章中就可以使用这个url了。
•metaWeblog.newPost新建随笔
•wp.newCategory这个函数似乎是博客园独有的,可以添加分类
这九大函数根据名称就能看出来分为三大家子,其中wp这一家只有一个”新建类别“函数,blogger这一家有弟兄俩,这两个函数都需要appKey,这appKey其实不是必要的,博客园中用不到;metaWeblog是最主要的,包括对随笔的增改查三种操作,其中查又分为两种操作:根据postid查询博客;查询最近博客。metaWeblog还包括一个上传文件操作。
七个结构体:
BlogInfo描述博客的id,url,博客名等信息;
Post描述随笔的发布日期,题目,类别,具体内容等信息;
CategoryInfo描述类别信息;
FileData描述如何传输文件,包括文件名及文件内容,其中文件内容采用base64编码,上传到服务器后返回一个url,FileData有三个成员变量
bits:文件内容,byte[]类型,推荐使用java.nio一句话的事:Files.readAllBytes(Paths.get("shq.jpg")):byte[]
name:文件名,后缀必须是\.jpg|\.gif|\.png|\.jpeg之一,也就是说只允许上传图片
type:文件类型(不需要设置,如果设置了,容易出错,返回500服务器内部错误),服务器自己会解析什么类型,无须告知。
URLData只包含一项URL,写的博客是一个html,里面嵌套着图片,图片以结构体的形式FileData用metaWeblog.newMediaObject上传到服务器,返回一个url,这样就可以在html中使用这个url了。
Enclosure包括长度,类型,URL三项。
Source包含url及名称两项
以上内容在博客园里可以找到:
方式一:管理>设置选项底部
方式二:在我的首页,ctrl+u查看网页源代码,<header>里面有一个RSD(really simple discovery),进入这个链接,它是一个XML,里面包含了博客园的weblog入口。
顺道说说RSS和RSD。
RSS:really simple syndication简易信息聚合,为了人们快速获取有效信息。
RSD:really simple discovery简易入口,为了人们快速找到网络服务入口。
这两者都是特定领域协议。
六.XML-RPC的数据类型
是不是顺序有点乱,觉得应该把这一部分放在前面。其实都行,学习就需要回环往复,由深入浅又由浅入深,没有必要按部就班,只要会了就行。
6种基本数据类型,2种组合数据类型。XML-RPC说:一切皆value。所以一共有八种value。
<value><int>2323</int></value> <value><double>23.23<double></value> <value><boolean>1或者0</boolean></value> <value><string>weidiao</string></value> <value><dateTime>20021125T02:20:04</dateTime></value>格式显而易见:yyyyMMddThh:mm:ss <value><base64>ASDFASD9823</base64></value>将任意二进制数据转换成base64编码方式。 <value><array><data>里面可以放多个value</data></array></value>我认为data这个标签有点多余 <value><struct>这里可以放多个member,每一个member都是一个name-value-pair</struct></value>
Basic Data Types in XML-RPC
| Type | Value | Examples |
|---|---|---|
| int or i4 | 32-bit integers between - 2,147,483,648 and 2,147,483,647. |
<int>27</int> <i4>27</i4> |
| double | 64-bit floating-point numbers |
<double>27.31415</double> <double>-1.1465</double> |
| Boolean | true (1) or false (0) |
<boolean>1</boolean> <boolean>0</boolean> |
| string | ASCII text, though many implementations support Unicode |
<string>Hello</string> <string>bonkers! @</string> |
| dateTime.iso8601 | Dates in ISO8601 format: CCYYMMDDTHH:MM:SS |
<dateTime.iso8601> 20021125T02:20:04 </dateTime.iso8601> <dateTime.iso8601> 20020104T17:27:30 </dateTime.iso8601> |
| base64 | Binary information encoded as Base 64, as defined in RFC 2045 |
<base64>SGVsbG8sIFdvcmxkIQ==</base64> |
两种组合数据类型:数组和结构体。数组表示了一种序列化信息,数组可以包含多种数据类型;结构体其实相当于映射,是键值对,是属性集,是关联数组。
基本数据类型在xml中表示如下:<value><type>xxxx</type></value>。除了string类型可以省略<type>标签外,其余五种基本数据类型必须明确注明数据类型(这一点就不要记了,统一处理,<value></value>必须注明数据类型)。
<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><string>dfdfdf</string></value>
<value><int>-91</int></value>
<value><int>42</int></value>
</data>
</array>
</value>
数组也可以嵌套的,很显然数组相当于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>
七.发出请求
请求的格式是http请求头部+xml的具体数据内容,通过post方式发送到服务器。
其中xml内容包括两大部分:方法名及参数,一旦进入<param></param>标签,就跟上面那些数据类型一样一样的了。
<?xml version="1.0"?>
<methodCall>
<methodName>circleArea</methodName>
<params>
<param>
<value><double>2.41</double></value>
</param>
</params>
</methodCall>
八.回复的格式
包括两部分:http头部+xml具体内容,跟发送时没多大区别。如你所见,既然有http头部,那就完全可以保存cookie。
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 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协议,不就是向服务器post字符串吗?post的时候有多种方式,可以同步可以异步,可以用原生的URLConnection也可以用封装过的HTTPClient。
于是问题转化为对xml串的生成和解析。xml的生成和解析也有很多库。完全可以自主开发出一套XML-RPC库。
九.接下来看什么
WSDL网络服务描述语言:基于XML描述了web服务的功能,消息格式以及协议细节.
SOAP:基于XML,用于程序之间通过http进行交流
十.内省方法
introspect
一个好的事物必然能够系统地告诉人们它的一切,而不是藏着掖着。任何好的开源组件都必然对应详尽的文档。
XML-RPC规定了三个保留方法用来内省服务器。
什么叫内省(xing),就是朝里看,对里面进行探测。
比如,根据数据库中的表自动生成实体类(PO,persistent object)叫内省;
在fastjson中把javaBean映射成map对象,需要探知Bean中的全部属性和get,set方法,这也叫内省;
使用XML-RPC时,调用这三个方法,就可以对服务器提供的可用方法有一个整体的认识。
人类都有一种感觉:如果对一样事物没有全局的把控,就不踏实。其实能够在这种不踏实的感觉下勇猛前行者,最终才能够变得踏实,要有一种反复咀嚼的精神。
system.listMethods 无参函数,返回全部方法
system.methodSignature 传入函数名称
system.methodHelp 传入函数名称
第一个函数,返回可用方法列表;第二个函数,返回方法签名;第三个函数返回函数详情。
至于返回值是什么类型的,可以通过java中的Object#getClass() 反射得到类型名称。
十一.XML-RPC的替代者
hessian基于二进制传递数据,速度快,但跨平台性比不上纯字符串格式的快.
JSON-RPC基于json串传递数据
XML-RPC远程方法调用的更多相关文章
- 简单实现Java的RMI——远程方法调用
一.RMI简介: 说到RMI就不得不说RPC了. RPC:(Remote Procedure Call),远程过程调用. RMI(Remote Method Invocation),远程方法调用. R ...
- Java APi 之 RMI远程方法调用
一.什么是RPC RPC全称是remote procedure call,即远程过程调用.它是一种协议,用于从远程计算机上请求服务. 例如有两台服务器A和B,A上的应用想要调用B上应用的方法,但是他们 ...
- [转]Java远程方法调用
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远 ...
- SpringBoot里使用RMI进行远程方法调用
一.Java RMI定义 Java RMI:Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程 ...
- RMI远程方法调用
RMI远程方法调用:适用于 客户端 调用 服务器 内的方法:(Kotlin 语言编写) 如果业务为二个服务器之间的通信,还是得用消息队列的形式,因为RMI 不适合 双向 调用 下面介绍RMI 的使用方 ...
- 【Java Web开发学习】远程方法调用RMI
Java RMI 远程方法调用Remote Method Invocation 转载:http://www.cnblogs.com/yangchongxing/p/9078061.html 1.创建远 ...
- Java RMI 远程方法调用
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- Java RMI远程方法调用
RMI(远程接口调用) 1. RMI的原理: RMI系统结构,在客户端和服务器端都有几层结构. 方法调用从客户对象经占位程序(Stub).远程引用层(Remote Reference Layer)和传 ...
- SpringRMI远程方法调用
Spring为各种远程访问技术的集成提供了工具类. 该小段引用自 http://www.open-open.com/lib/view/open1408957290478.html Spring远程支持 ...
随机推荐
- x01.os.13: 文件系统
停了两天电,忽然得空闲.找来破吉他,已然不成弦. 丁丁当当敲,敲到电来到.为把时间捡,熬夜三四点. 从我的置顶随笔 x01.Lab.Download 中下载 x01.os.12.t ...
- linux面试题
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取uu要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 ...
- android MotionEvent 获取长按压时间长
思路: 1.记录ACTION_DOWN的aX, aY坐标: 2.在ACTION_MOVE判断是否移动,移动则取消记录时间,没移动就记录: 3.记录时间,按下坐标,移动坐标分别显示在TextView a ...
- XSS Payload知识备忘
参考资料:<白帽子讲Web安全>吴翰清 著 参见: 百度百科 http://baike.baidu.com/view/50325.htm 维基百科 http://zh.wikipedia. ...
- sql索引的填充因子多少最好,填充因子的作用?
当创建一个新索引,或重建一个存在的索引时,你可以指定一个填充因子,它是在索引创建时索引里的数据页被填充的数量.填充因子设置为100意味着每个索引页100%填满,50%意味着每个索引页50%填满. 如果 ...
- wk_04
函数 函数是对程序逻辑进行结构化或过程化的一直编程方法.能将整块代码巧妙的隔离成易于管理的小块,把重复代码放到函数中而不是进行大量的拷贝--这样既能节省空间,也有助于保持一致性,因为你只需要改变单个的 ...
- XMAPP配置
F:\xmapp\apache\conf\extra httpd-vhosts.conf peizhi##<VirtualHost *:80> ## DocumentRoot " ...
- CentOS 6.4 下安装vsftpd
概述: vsftpd是Linux下比较著名的FTP服务器,搭建FTP服务器当然首选这个. 本文介绍了在CentOS 6.4下安装vsftpd.配置虚拟用户登录FTP的过程. 正文: 一:安装vsftp ...
- tree命令的使用
有些工作在linux下完成就是比在windows下完成高效! windows和linux都有tree命令,主要功能是创建文件列表,将所有文件以树的形式列出来 windows下的tree比较垃圾,只有两 ...
- Basic: Fisher's transform
来源:http://bbs.chinahrd.net/thread-709742-1-1.html,Kenneth的回答. z = 0.5 * ln [ (1+r)/(1-r) ]" C0 ...