JAVA—咖啡館

          ——歡迎訪問rogerfan的博客,常來《JAVA——咖啡館》坐坐,喝杯濃香的咖啡,彼此探討一下JAVA技術(shù),交流工作經(jīng)驗,分享JAVA帶來的快樂!本網(wǎng)站部分轉(zhuǎn)載文章,如果有版權(quán)問題請與我聯(lián)系。

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            447 Posts :: 145 Stories :: 368 Comments :: 0 Trackbacks

          一、概述

          SOAP原意為Simple Object Access Protocol(簡單對象訪問協(xié)議),是一個用于分布式環(huán)境的、輕量級的、基于XML進(jìn)行信息交換的通信協(xié)議(SOAP is an XML based protocol used to exchange information throughout a distributed environment)。

          以下是w3c網(wǎng)站上的定義:

          SOAP Version 1.2 (SOAP) is a lightweight protocol intended for exchanging structured information in a decentralized, distributed environment. It uses XML technologies to define an extensible messaging framework providing a message construct that can be exchanged over a variety of underlying protocols. The framework has been designed to be independent of any particular programming model and other implementation specific semantics.

          可以認(rèn)為SOAPXML-RPC的高級版本,二者基于相同的原理:利用HTTP + XML封裝進(jìn)行RPC調(diào)用。

          SOAP最初由MS發(fā)起研究,用以解決MTS/COM資源消耗大,不夠輕巧等問題,后逐漸被IBM等巨頭接納并加入研究,現(xiàn)已提交W3C,成為Web Service應(yīng)用傳輸標(biāo)準(zhǔn)。對于輕量級、可擴展Web Service應(yīng)用協(xié)議的需求促成了SOAP的廣泛應(yīng)用,也間接促進(jìn)了XML的流行。關(guān)于相關(guān)歷史的更多信息,見http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/SOAPSpecificationIndexPage.mspxhttp://www-128.ibm.com/developerworks/cn/webservices/ws-ref1/index.html

          二、SOAP數(shù)據(jù)包結(jié)構(gòu)解析

          SOAP的消息被稱為一個SOAP Envelope,包括SOAP HeaderSOAP Body。其中,SOAP Header可以方便的插入各種其它消息來擴充Web Service的功能,比如Security(采用證書訪問Web Service),SOAP Body則是具體的消息正文,也就是Marshall后的信息。

          SOAP調(diào)用的時候,也就是向一個URL(比如http://api.google.com/search/beta2)發(fā)送HTTP Post報文(根據(jù)SOAP規(guī)范,HTTP Get報文也可被支持),調(diào)用方法的名字在HTTP Request Header SOAP-Action中給出,接下來就是SOAP Envelope了。服務(wù)端接到請求,執(zhí)行計算,將返回結(jié)果MarshallXML,用HTTP返回給客戶端。

          以下是一個典型的SOAP數(shù)據(jù)包:

          <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">

                <s:Header>

                      <m:transaction xmlns:m="soap-transaction" s:mustUnderstand="true">

                            <transactionID>1234</transactionID>

                      </m:transaction>

                </s:Header>

                <s:Body>

                      <n:purchaseOrder xmlns:n="urn:OrderService">

                            <from>

                                  <person>Christopher Robin</person>

                                  <dept>Accounting</dept>

                            </from>

                            <to>

                                  <person>Pooh Bear</person>

                                  <dept>Honey</dept>

                            </to>

                            <order>

                                  <quantity>1</quantity>

                                  <item>Pooh Stick</item>

                            </order>

                      </n:purchaseOrder>

                </s:Body>

          </s:Envelope>

          其中包含了一些SOAP規(guī)范定義的標(biāo)簽,同時也可以包含一些具體應(yīng)用相關(guān)的標(biāo)簽。

          Note:

          如果你是一個普通的應(yīng)用開發(fā)者,以上介紹已經(jīng)足夠了,因為相應(yīng)的SOAP應(yīng)用平臺會負(fù)責(zé)完成相應(yīng)SOAP數(shù)據(jù)包的打包和解析;如果你是一個SOAP應(yīng)用平臺的實現(xiàn)者,關(guān)于SOAP基礎(chǔ)理論的更多介紹可參考《Programming Web Services with SOAP》一書或SOAP Specificationhttp://www.w3.org/TR/soap12-part0/)。

          三、安裝Apache Axis

          Apache Axis本身也是一個Web Project,它內(nèi)建了對SOAP的編碼、解析,并為Client提供了一些使用SOAP ServiceAPI,同時,為Web Service的發(fā)布提供管理,并對Client提交的處理請求作出響應(yīng)。對于基于Axis的應(yīng)用而言,我們可以將注意力完全放在具體ServiceClient的設(shè)計上,而無需考慮中間的傳輸過程(對于Client而言,還需要使用一些Axis提供的訪問SOAP服務(wù)的特定API),這一點是與XML RPC不同的地方。

          Apache Axis可以從http://ws.apache.org/axis/下載,當(dāng)前的最新版本是1.4

          安裝Axis的過程很簡單:

          1、解壓Axis到任意目錄下;

          2、拷貝Axis目錄下的webapps/axis目錄到%TOMCAT_HOME%/webapps下;

          3、為了便于編譯和測試程序,添加環(huán)境變量:

          AXIS_HOME      Axis的解壓目錄

          AXIS_LIB      %AXIS_HOME%/lib

          AXISCLASSPATH      %AXIS_LIB%/axis.jar;%AXIS_LIB%/commons-discovery-0.2.jar;%AXIS_LIB%/commons-logging-1.0.4.jar;%AXIS_LIB%/jaxrpc.jar;%AXIS_LIB%/saaj.jar;%AXIS_LIB%/log4j-1.2.8.jar

          完成上述工作后,啟動Tomcat,并用IE打開:http://localhost:8080/axis/,點擊其中的ValidationList兩個鏈接,如果沒有報告任何錯誤,則說明Axis安裝成功。

          關(guān)于Apache Axis安裝的更多信息可以參考官方文檔:http://ws.apache.org/axis/java/install.pdf

          四、舉例

          有了上面對SOAP的基本理解,下面我們體驗一下Apache Axis 1.4提供的SOAP服務(wù)。

          以下面EchoService為例:

          public class EchoService {

                public String echoString(String name) {

                      return name;

                }

          }

          其對應(yīng)的Client程序如下所示:

          package demo.soap;

           

          import org.apache.axis.client.Call;

          import org.apache.axis.client.Service;

           

          import javax.xml.namespace.QName;

           

          public class EchoClient {

                public static void main(String [] args) {

                      try {

                            String endpoint = "http://localhost:8080/axis/EchoService.jws";

                            // Create Service and Call object to set up a SOAP RPC

                            Service service = new Service();

                            Call call = (Call)service.createCall();

                            // Tells which service and method will be invoked

                            call.setTargetEndpointAddress(new java.net.URL(endpoint));

                            call.setOperationName(new QName("echoString"));

                            // Invoke method with required parameters

                            String ret = (String)call.invoke(new Object[] { "Hello!" });

           

                            System.out.println("Sent 'Hello!', got '" + ret + "'");

                      } catch (Exception e) {

                            System.err.println(e.toString());

                      }

                }

          }

          對于Client程序而言,對Axis Service進(jìn)行訪問的基本方法是:

          1、創(chuàng)建ServiceCall對象;

          2、設(shè)置Call對象屬性,如訪問點(標(biāo)明將訪問哪個Axis Service)及方法名等;

          3、傳入?yún)?shù)數(shù)組,調(diào)用Call對象的invoke方法。

          可使用如下命令編譯EchoClient.java

          javac -cp %AXISCLASSPATH% EchoClient.java

          Axis中,存在兩種發(fā)布SOAP Service的方法。

          方法一:

          將源程序EchoService.java拷貝到%TOMCAT_HOME%/webapps/axis下,并將其后綴改為.jws即可。

          第一種方法非常的簡單,但是第一種發(fā)布方法存在幾個重要的限制:

          1、不能指定package

          2、需要有Service的源碼;

          因此常常不能滿足我們的需要。

          方法二:

          第二種發(fā)布Axis Service的方法需通過配置來完成。

          以下面的HelloService為例(與前面的EchoService基本沒有什么區(qū)別,但其中使用了package):

          package demo.soap;

           

          public class HelloService {

                public String sayHello() {

                      return "Hello World!";

                }

          }

          要發(fā)布上面的Service,需編寫如下的配置文件:

          <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

                <service name="HelloService" provider="java:RPC">

                      <parameter name="className" value="demo.soap.HelloService"/>

                      <parameter name="allowedMethods" value="*"/>

                </service>

          </deployment>

          將上述內(nèi)容保存為%TOMCAT_HOME%/webapps/axis/WEB-INF/deploy.txt,并在其所在目錄下執(zhí)行:

          java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.txt

          生成server-config.wsdd文件,打開該文件看一下,可以看到HelloService的相關(guān)信息已被添加到該文件,此外,還包括一些默認(rèn)的配置信息以及AdminServiceVersion兩個基礎(chǔ)服務(wù)。

          以下是HelloServiceClient程序的相關(guān)代碼:

          package demo.soap;

           

          import org.apache.axis.client.Call;

          import org.apache.axis.client.Service;

           

          public class HelloClient {

                public static void main(String [] args) throws Exception {

                      String endpoint = "http://localhost:" + "8080" + "/axis/services/HelloService"; // Attention: A little difference

           

                      Service service = new Service();

                      Call call = (Call)service.createCall();

                      call.setTargetEndpointAddress(new java.net.URL(endpoint));

                      call.setOperationName("sayHello");

           

                      String res = (String)call.invoke(new Object[] {});

           

                      System.out.println(res);

                }

          }

          與前面的EchoClient的區(qū)別僅在于訪問點稍有不同。

          發(fā)布后如何刪除對應(yīng)的Service呢?要刪除上面發(fā)布的HelloService服務(wù),只需在%TOMCAT_HOME%/webapps/axis/WEB-INF目錄下添加如下的undeploy.txt描述文件,其內(nèi)容如下:

          <undeployment xmlns="http://xml.apache.org/axis/wsdd/">

                <service name="HelloService"/>

          </undeployment>

          然后執(zhí)行:

          java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.txt

          以更新server-config.wsdd文件。

          刷新一下頁面:

          http://localhost:8080/axis/servlet/AxisServlet

          將看到前面已發(fā)布的對應(yīng)的Service已被刪除。

          如果以后還要發(fā)布新的Service,你可以選擇直接更新上面產(chǎn)生的server-config.wsdd文件,或者重復(fù)上面的步驟。

          Note:除了發(fā)布自己的Web ServiceAxis,你也可以將Axis集成到自己的Web Application,具體方法見http://ws.apache.org/axis/java/install.pdf

          五、Google Web API

          在繼續(xù)下面的討論之前,先娛樂一下,談?wù)?/span>Google Web API

          為了便于程序員體驗Google的搜索服務(wù),或者將Google的搜索服務(wù)集成到自己的應(yīng)用中,Google2002發(fā)布了Google Web API,可以讓世界各地的Java.NETPerlPython等程序員,免費地通過Google提供的SOAP開發(fā)接口以Web Services的方式,對Google下達(dá)查找指令,并且可以將結(jié)果使用于自己的程序或網(wǎng)頁中。(不過使用上也有限制,它一天只允許未付費的程序員查找1000次。要使用前,必須先向Google注冊帳號,取得一個32位長度的license key,每次呼叫查詢時,必須帶入這個license key。)

          通過使用Google Web API,能夠從Google那兒以結(jié)構(gòu)化數(shù)據(jù)的形式(xml格式)取得檢索結(jié)果,所帶來的最大好處就是你可以根據(jù)你自己的意愿和設(shè)計,把這些檢索結(jié)果顯示你自己的頁面上。這個頁面上可顯示自己的logo或一些其它的內(nèi)容,就象自己編寫的頁面一樣,而不必非要把Googlelogo顯示在頁面的頂部和底部。一句話,你可以控制Google的檢索了,讓Google為你的網(wǎng)站服務(wù)。(參考5

          以下是使用Proxy連接Google SOAP服務(wù)的例子:

          java -cp googleapi.jar -Dhttp.proxyHost=xxx(proxy_host_ip/name) -Dhttp.proxyPort=xxx(proxy_port) com.google.soap.search.GoogleAPIDemo xxx(license_key) search billdavid

          其輸出大致如下:

          Parameters:

          Client key = o917zHlQFHIr2+qMGPUYflB+j89LLbcX

          Directive = search

          Args       = billdavid

          Google Search Results:

          ======================

          {

          TM = 0.694308

          Q = "billdavid"

          CT = ""

          TT = ""

          CATs =

           {

           <EMPTY>

           }

          Start Index = 1

          End   Index = 10

          Estimated Total Results Number = 1280

          Document Filtering = true

          Estimate Correct = false

          Rs =

           {

           

           [

           URL = "http://forums.vandyke.com/member.php?u=2050"

           Title = "VanDyke Software Forums - View Profile: <b>billdavid</b>"

           Snippet = "This is a discussion forum for users and evaluators of VanDyke Soft

          ware products."

           Directory Category = {SE="", FVN=""}

           Directory Title = ""

           Summary = ""

           Cached Size = "16k"

           Related information present = true

           Host Name = ""

           ],

           

           [

           URL = "http://forums.vandyke.com/showthread.php?t=1393"

           Title = "Will you add two new features to SecureCRT? - VanDyke Software Forums

          "

           Snippet = "<b>billdavid billdavid</b> is offline. Registered User. Join Date:

          Apr 2006 <b>...</b><br> Originally Posted by <b>billdavid</b>. I think the foll

          owing features are very useful: <b>...</b>"

           Directory Category = {SE="", FVN=""}

           Directory Title = ""

           Summary = ""

           Cached Size = "30k"

           Related information present = true

           Host Name = "forums.vandyke.com"

           ],

           

           [

           URL = "http://www.beliefnet.com/user/profile_view.asp?userID=424089&popUp=1"

            Title = "Beliefnet Member Profile"

           Snippet = "Member Name: <b>billdavid</b>. Member since: 2/24/2003. Location: s

          ebring, florida , us.<br> Sex: Male. Age: 53. Occupation: Other. Organizations

          and Affiliations: <b>...</b>"

           Directory Category = {SE="", FVN=""}

           Directory Title = ""

           Summary = ""

           Cached Size = "8k"

           Related information present = true

           Host Name = ""

           ],

          (下略...

          以下是通過ethereal抓到的本機發(fā)出的Google Search數(shù)據(jù)包:

          POST http://api.google.com/search/beta2 HTTP/1.0

          Host: api.google.com

          Content-Type: text/xml; charset=utf-8

          Content-Length: 864

          SOAPAction: "urn:GoogleSearchAction"

          <?xml version='1.0' encoding='UTF-8'?>

          <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">

                <SOAP-ENV:Body>

                      <ns1:doGoogleSearch xmlns:ns1="urn:GoogleSearch" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

                            <key xsi:type="xsd:string">xxx…xxx</key>

                            <q xsi:type="xsd:string">billdavid</q>

                            <start xsi:type="xsd:int">0</start>

                            <maxResults xsi:type="xsd:int">10</maxResults>

                            <filter xsi:type="xsd:boolean">true</filter>

                            <restrict xsi:type="xsd:string"></restrict>

                            <safeSearch xsi:type="xsd:boolean">false</safeSearch>

                            <lr xsi:type="xsd:string"></lr>

                            <ie xsi:type="xsd:string">UTF-8</ie>

                            <oe xsi:type="xsd:string">UTF-8</oe>

                      </ns1:doGoogleSearch>

                </SOAP-ENV:Body>

          </SOAP-ENV:Envelope>

          com.google.soap.search.GoogleAPIDemo.java的源代碼可以在googleapi的壓縮包中找到,其中演示了大部分基本Google Web API的用法,關(guān)于Google Web API的更多信息見參考4

          六、Axis2

          隨著Web Services技術(shù)的演進(jìn),Apache Web Services中間件也在不斷發(fā)展,從第一代的Apache SOAP,第二代的Axis,逐漸發(fā)展成為第三代Web Service中間件Axis2。與Axis相比,Axis2采用了性能更為優(yōu)越的XML解析技術(shù),采用面向組件的架構(gòu)設(shè)計,從而具有更好的靈活性和可擴展性,并可支持異步通信需求等。參考67給出了利用Axis2進(jìn)行Web Service開發(fā)的詳細(xì)步驟。

          參考:

          1.   勞虎,SOAPWeb serviceshttp://2tigers.net/html/tiger_column/article3.html

          2.   孟巖,Web Service : WebOS中的Function Callhttp://www.mengyan.org/blog/archives/2006/06/09/125.html

          3.   Axis學(xué)習(xí)筆記,http://www.javaresearch.org/article/showarticle.jsp?column=5&thread=29576

          4.   Google, Google SOAP Search API, http://www.google.com/apis/

          5.   Patrick Chanezon, Patch For Google APIs to handle proxy settings, http://www.chanezon.com/pat/google_proxy_patch.html

          6.   Hilton,關(guān)于Google API的學(xué)習(xí),http://hedong.3322.org/archives/000274.html

          7.   Gopalakrishnan UShreevidya Rao,通過Axis2開發(fā)Web服務(wù),http://www-128.ibm.com/developerworks/cn/webservices/ws-webaxis1/index.html

          8.   joyetaApache Axis2(java web service)備忘記,http://blog.matrix.org.cn/page/joeyta?entry=apache_axis2_java_web_service

          posted on 2011-09-24 10:22 rogerfan 閱讀(1628) 評論(0)  編輯  收藏 所屬分類: 【Java知識】
          主站蜘蛛池模板: 西华县| 宜兴市| 沅江市| 太仆寺旗| 房产| 麻栗坡县| 托克逊县| 历史| 洞口县| 比如县| 德格县| 永宁县| 乌鲁木齐市| 营山县| 京山县| 济宁市| 阳泉市| 乡宁县| 鄂尔多斯市| 永年县| 岳池县| 南阳市| 正阳县| 亚东县| 通辽市| 泸水县| 徐水县| 鹤壁市| 天峻县| 瑞昌市| 桐梓县| 万荣县| 武陟县| 定安县| 扶余县| 扎囊县| 德昌县| 普安县| 隆安县| 靖西县| 赣州市|