posts - 28,comments - 3,trackbacks - 0
          系統用純HTTP+POST+XML的方式來進行信息溝通:XML是信息的載體、HTTP是傳遞的協議、POST是傳遞的方式。也就是說這和Web Service沒什么關系。Web Service現在有兩種不同實現SOAP和XML-RPC,XML-RPC(RPC是遠程調用的意思)有一個開源的產品,其實現的低層也是基于HTTP+POST+XML的方式。我本來打算用純Servlet就解決這個項目了,但老大說這樣不行,可擴展性太差,因為福建是純HTTP、也許廣東就是SOAP或其他的方式,而且其中還存在一些構架設計等等方面的東東。

          最后,我得到的要求和提示就是基于XML-RPC來實現這個項目,但XML-RPC是遠程調用的方式,而福建BOSS并非遠程調用,所以需要修改一下XML- RPC的源代碼(老大花了一個下午改好了,而我花了一周多去研讀和完整,水平不是一個數量級的呀,郁悶一下)。修改后的XML-RPC,在遠程調用的實現外,再提供了一個純 HTTP+POST的現實方式。

          注:本篇不涉及到修改XML-RPC的源代碼。

          2.2 XML- RPC簡介

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

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

          2.3 XML-RPC的下載

          1、我的環境

          WindowsXP SP2 + JDK1.4.2_6 + Eclipse3.0.1

          2、XML-RPC

          l           版 本:v1.2-b1 

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

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

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

          3、SAX實現包: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  創建服務端程序

          1、HelloServer

          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) {

                  //使用Xerces的XML 解析器

                  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中。

          2、HelloHandler

          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  創建客戶端程序

          1、HelloClient

          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方式來運行HelloServer。Eclipse的“控制臺 ”顯示如下圖:

          2、運行客戶端

          以Application方式來運行HelloClient。Eclipse的“控制臺 ”顯示如下圖:

          2.5  XML- RPC原理分析

          2.5.1 XML-RPC所傳輸的XML文件

          在上面的例程中說了,XML-RPC將遠程方法的調用,實際是封裝成一個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改成8070。HelloServer還是原來的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>& lt;params><param><value>ChenGang</value></param>&l t;/params></methodCall>

           

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

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

          <methodCall>

              <methodName>hello_id.sayHello</methodName>

              <params>

                  <param>

                    &nbs p; <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>

                    &nbs p; <value>Hello World, ChenGang</value>

                  </param>

              </params>

          </methodResponse>

          2.5.2  客戶端的處理流程

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

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

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

          posted on 2007-05-24 11:18 李大嘴 閱讀(1256) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 马尔康县| 青浦区| 满洲里市| 峨边| 马关县| 大埔区| 库伦旗| 鄂尔多斯市| 辽阳县| 高雄县| 伽师县| 文昌市| 抚远县| 佛教| 卫辉市| 疏勒县| 社旗县| 黎城县| 双流县| 河西区| 泗阳县| 宁津县| 广宗县| 淮安市| 阳信县| 民权县| 措美县| 仁布县| 荃湾区| 临汾市| 龙海市| 株洲市| 邹平县| 郸城县| 焦作市| 普陀区| 昆山市| 盐津县| 绥宁县| 文化| 临武县|