XML-RPC远程方法调用
?一.簡介
XML-RPC的全稱是XML Remote Procedure Call,即XML遠程方法調用。
它是一套允許運行在不同操作系統、不同環境的程序實現基于Internet過程調用的規范和一系列的實現。 這種遠程過程調用使用http作為傳輸協議,XML作為傳送信息的編碼格式。 XML-RPC的定義盡可能的保持了簡單,但同時能夠傳送、處理、返回復雜的數據結構。
XML-RPC是使用HTTP協議做為傳輸協議的RPC(遠程方法調用)機制,使用XML文本的方式傳輸命令和數據。 一個RPC系統,必然包括2個部分: 1.RPC Client,用來向RPC Server調用方法,并接收方法的返回數據; 2.RPC Server,用于響應RPC Client的請求,執行方法,并回送方法執行結果。 RPC是Remote Procedure Call的縮寫,翻譯成中文就是遠程方法調用,是一種在本地的機器上調用遠端機器上的一個過程(方法)的技術,這個過程也被大家稱為“分布式計算”,是為了提高各個分立機器的“互操作性”而發明出來的技術。?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() {@Overridepublic XmlRpcHandler getHandler(String handlerName)throws XmlRpcNoSuchHandlerException, XmlRpcException {switch (handlerName) {case "add" :return new XmlRpcHandler() {@Overridepublic 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() {@Overridepublic 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;@Overridepublic int getParameterCount() {return 2;}@Overridepublic Object getParameter(int x) {if (x == 0)return this.x;elsereturn this.y;}@Overridepublic String getMethodName() {return "add";}@Overridepublic 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
| 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>標簽,就跟上面那些數據類型一樣一樣的了。
八.回復的格式
包括兩部分: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远程方法调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [android] 网络html查看器
- 下一篇: 史上最全JS表单验证封装类