[轉]XML-RPC的HelloWorld實例

2  XML-RPCHelloWorld實例

2.1         前言

經過研究以及和BOSS系統的開發方溝通,發現此BOSS系統是用純HTTPPOST+XML的方式來進行信息溝通:XML是信息的載體、HTTP是傳遞的協議、POST是傳遞的方式。也就是說這和Web Service沒什麼關係。Web Service現在有兩種不同實現SOAPXMLRPCXML-RPCRPC是遠程調用的意思)有一個開源的產品,其實現的低層也是基於HTTPPOST+XML的方式。我本來打算用純Servlet就解決這個項目了,但老大說這樣不行,可擴展性太差,因爲福建是純HTTP、也許廣東就是SOAP或其他的方式,而且其中還存在一些構架設計等等方面的東東。

最後,我得到的要求和提示就是基於XMLRPC來實現這個項目,但XMLRPC是遠程調用的方式,而福建BOSS並非遠程調用,所以需要修改一下XMLRPC的源代碼(老大花了一個下午改好了,而我花了一週多去研讀和完整,水平不是一個數量級的呀,鬱悶一下)。修改後的XMLRPC,在遠程調用的實現外,再提供了一個純HTTPPOST的現實方式。

注:本篇不涉及到修改XMLRPC的源代碼。

2.2 XML-RPC簡介

XMLRPCApacheWeb Service方面的一個項目,官方網址:http://ws.apache.org/xmlrpc/ ,其中的RPCremote procedure call是遠程調用的意思,它本身是通過HTTP進行傳輸,用XML做傳遞信息的載體。XMLRPC是一個規範很簡單的軟件框架,也是Web Service的最早的實現,不過現在SOAP似乎比XMLRPC更流行。

上圖反映了XMLRPC的轉輸方式:數據(DATA)和所要調用的方法被封裝到一個XML中,然後由XMLRPC簡單的HTTPPOST到服務端。服務端也裝有XMLRPC來接收客戶端的XML文件,並將接收到的XML信息進行分解,然後根據XML中記載的信息調用服務端的相應的方法。

2.3 XMLRPC的下載

1、我的環境

WindowsXP SP2 + JDK1.4.2_6 + Eclipse3.0.1

2XMLRPC

l           版 本:v1.2-b1 

l           文件名:xmlrpc-1.2-b1.zip(下載後還要解壓一下,得到xmlrpc-1.2-b1.jar

l           下 載:http://apache.justdn.org/ws/xmlrpc/ 

l           其 它:爲了追蹤XMLRPC的代碼執行過程,最好把它的源代碼包一起下了,文件名:xmlrpc-1.2-b1-src.zip

3SAX實現包:xerces

因爲XML-RPC中設及到XML文件的解析等操作,它採用了SAX方式,所以它需要一個SAX實現包的支持。SAX的實現有很多種,我選擇了xerces

l           版 本:v1.4.4  (版本老了點,是2001年的,不過夠用了)

l           文件名:Xerces-J-bin.1.4.4.zip(下載後還要解壓一下,得到xerces.jar

l           下 載:http://xml.apache.org/dist/xerces-j/ 

2.4         Hello World實例

我一直認爲實例和代碼是最好的說明,還是少說廢話,先來個最簡單的Hello World實例來體會一下吧。

2.4.1 創建項目

由於我用的是Eclipse,所以先創建一個普通的JAVA項目myxmlrpc,然後將xerces.jar xmlrpc-1.2-b1.jar複製到項目的lib目錄。再創建一個包:cn.com.chengang.xmlrpc,以後就在此包下寫程序。如下圖:

2.4.2  創建服務端程序

1HelloServer

package cn.com.chengang.xmlrpc;

 

import org.apache.xerces.parsers.SAXParser;

import org.apache.xmlrpc.WebServer;

import org.apache.xmlrpc.XmlRpc;

 

public class HelloServer {

    public static void main(String[] args) {

        //使用XercesXML解析器

        XmlRpc.setDriver(SAXParser.class);

        System.out.println("啓動一個WEB SERVER, 端口號:8989");

        WebServer server = new WebServer(8989);

        server.start();

        //HelloHandler類的實例綁定到WEB SERVER上,hello是該處理類的id標識,在客戶端調用時要用得到

        server.addHandler("hello_id", new HelloHandler());

    }

}

說明:

這個文件主要是啓動了一個Web Server,並將一個HelloHandler類加到server中。

2HelloHandler

package cn.com.chengang.xmlrpc;

 

public class HelloHandler {

    public String sayHello(String name) {

        return "Hello World, " + name;

    }

}

說明:

HelloHandler類不需要實現或繼承任何接口抽象類,它的作用就是做爲服務器端的處理程序,所有處理邏輯都在Handler類裏來實現。我們可以寫上很多的Handler類,並且一個Handler類裏可以有很多的方法(這裏有一個sayHello方法)。

2.4.3  創建客戶端程序

1HelloClient

package cn.com.chengang.xmlrpc;

 

import java.io.IOException;

import java.util.Vector;

 

import org.apache.xerces.parsers.SAXParser;

import org.apache.xmlrpc.XmlRpc;

import org.apache.xmlrpc.XmlRpcClient;

import org.apache.xmlrpc.XmlRpcException;

 

public class HelloClient {

    public static void main(String args[]) throws XmlRpcException, IOException {

        //使用 Apache Xerces SAX 解析器

        XmlRpc.setDriver(SAXParser.class);

        //定位遠程服務器

        XmlRpcClient client = new XmlRpcClient("http:// 127.0.0.1:8989");

        //創建調用請求,方法的參數列表用一個Vector對象來存儲。

        Vector params = new Vector();

        params.addElement("ChenGang");

        //發出請求,並返回結果,execute需要兩個參數,第一個參數用“Handler的標識名.方法名”,第二參數是一個剛剛建立的向量對象

        String result = (String) client.execute("hello_id.sayHello", params);

        System.out.println("服務器的返回值: " + result);

    }

}

說明:

l           客戶端的程序比較簡單,主要是通過XmlRpcClient類來將要調用的服務器端Handler的方法名(Handler的標識),及這個方法的參數(params),傳遞給服務端。

l           在這裏127.0.0.1是指本機,因爲服務端和客戶端都是在本機運行的,共用同一臺電腦。實際運行時,應該是分屬在兩臺電腦上的,這時把127.0.0.1改成真實的服務器IP即可。

l           8989就是HelloServer類中啓動Web Server的端口號。

l           有人說這裏並沒有看到XML文件的影子呀。其實client.execute("hello_id.sayHello", params);這一句已經封裝了所有的處理過程,表面上它只是方法名和方法參數,但內部在處理時會將這兩者處理成一個XML文件,然後POST到服務端。

l           params.addElement("ChenGang");的參數不能是中文,否則報錯。暫未找到解決方法。

2.4.4 運行

1、啓動服務

Application方式來運行HelloServerEclipse的“控制檯”顯示如下圖:

2、運行客戶端

Application方式來運行HelloClientEclipse的“控制檯”顯示如下圖:

2.5  XML-RPC原理分析

2.5.1 XML-RPC所傳輸的XML文件

在上面的例程中說了,XMLRPC將遠程方法的調用,實際是封裝成一個XML文件傳給服務器端的,那麼我們就來看看這個XML的樣子是怎麼樣的。

1、啓動監聽器

在上一篇所說的SOAP中有一個監聽器,我們把它運行起來。這個監聽器可以監聽本機上發送到某一個端口的信息。這的監聽器的入口類爲TcpTunnelGui,啓動此監聽器的命令如下:

java  org.apache.soap.util.net.TcpTunnelGui  8070  localhost  8989

如果報以下錯誤

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/soap/util/net/TcpTunnelGui

這是因爲soap.jar沒有定義在classpath變量中,你可以將soap.jar加入到系統變量classpath,也可以在命令中用-cp參數臨時指定soap.jar的位置。

java -cp "D:/soap-2_3_1/lib/soap.jar"  org.apache.soap.util.net.TcpTunnelGui  8070  localhost  8989

這樣所有發向8070端口的信息將被截獲,然後這個監聽器再把截獲的信息轉發到8989端口。此監聽器的界面如下,左邊是發出的信息,右邊是從服務端接收的信息。

注意:HelloClient類中的服務器端口號要由8989改成8070HelloServer還是原來的8989,不用改。

2、客戶端發出的XML信息

POST / HTTP/1.1

Content-Length: 165

Content-Type: text/xml

Cache-Control: no-cache

Pragma: no-cache

User-Agent: Java/1.4.2_06

Host: 127.0.0.1:8070

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

Connection: keep-alive

 

<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>hello_id.sayHello</methodName><params><param><value>ChenGang</value></param></params></methodCall>

 

XML的信息是一行,我把它格式化一下,如下:

<?xml version="1.0" encoding="ISO-8859-1"?>

<methodCall>

    <methodName>hello_id.sayHello</methodName>

    <params>

        <param>

            <value>ChenGang</value>

        </param>

    </params>

</methodCall>

3、服務端返饋的信息

HTTP/1.1 200 OK

Server: Apache XML-RPC 1.0

Connection: close

Content-Type: text/xml

Content-Length: 144

 

<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse><params><param><value>Hello World, ChenGang</value></param></params></methodResponse>

XML的信息是一行,我把它格式化一下,如下:

<?xml version="1.0" encoding="ISO-8859-1"?>

<methodResponse>

    <params>

        <param>

            <value>Hello World, ChenGang</value>

        </param>

    </params>

</methodResponse>

2.5.2  客戶端的處理流程

HelloClient的代碼中,我們看到是通過XML-RPC中的XmlRpcClient類來處理客戶端的請求的,XmlRpcClient的內部處理邏輯如上,WorkerXmlRpcClient的一個內部類。Worker主要是將“要調用的遠程方法以及方法參數”寫成一個XMLXML文件的格式在上面“2.5.1 2、客戶端發出的XML信息”已經給出了。

2.5.3 服務器端的處理流程(省略)

我修改的XMLRPC源代碼不是這個版本的,而是從ApacheCVS上直接check下來的,最新的開發中,其設計已經發生了一些變化。比如,客戶端的XML發送,原版是用HTTP+POST過去的,最新的則將它封成了一個接口:XmlRpcTransport,一個實現是HTTPPOST,另一個實現則是EMAIL的方式,這樣擴展性就更大了。

2.6  參考資料

xml-rpc入門例程及一個通用服務器(CSDN),地址:http://dev.csdn.net/develop/article/39/article/38/38300.shtm 

 

相關文章

 

發佈了6 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章