狼愛上貍

          我胡漢三又回來了

          AXIS全攻略(二)

          六、服務(wù)的訪問

            GET方式的服務(wù)訪問

            一般的SOAP消息都是采用POST方式實現(xiàn)傳遞,但也可以通過GET方式來訪問。比如以下給出的一個服務(wù)——“HelloWorld”,其源碼如下:

          文件HelloWorld.jws
          public class HelloWorld
          {
              public String helloWorld()
              {
                    System.out.println( "Hello World!" );//在服務(wù)器端打印輸出 
                    return "Hello World!";//返回相應(yīng)字符串
              }
          }

            這個服務(wù)給出一個名為“helloWorld”的無入口參數(shù)的操作,返回一個內(nèi)容為“Hello World!的字符串”,同時在服務(wù)器端打印“Hello World!”,將該文件放到“……\webapps\axis”目錄下,即可通過GET方法直接訪問該服務(wù),訪問的地址為http://localhost:8080/axis/HelloWorld.jws?method=helloWorld,可以看到返回的SOAP信封消息,同時服務(wù)器端給出了相應(yīng)的顯示信息“Hello World!”這表明HelloWorld服務(wù)被成功訪問了,生成的SOAP信封消息為:
           <?xml version="1.0" encoding="UTF-8" ?>
          - <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          - <soapenv:Body>
          - <helloWorldResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <helloWorldReturn xsi:type="xsd:string">Hello World!</helloWorldReturn>
            </helloWorldResponse>
            </soapenv:Body>
            </soapenv:Envelope>

           


          七、客戶端服務(wù)訪問編程

            Axis提供了一套API來實現(xiàn)SOAP,從http://localhost:8080/axis/docs/apiDocs/index.html可以看到Axis的API文檔。

            其中,org.apache.axis.client.Call和org.apache.axis.client.Service是兩個比較常用的類,一般的客戶端程序欲訪問一個Web Service時,都要生成一個客戶端的Service對象和Call對象,在訪問服務(wù)之前,首先要對Call對象設(shè)置相應(yīng)的參數(shù),包括服務(wù)的位置、操作名、入口參數(shù)、返回值類型等,最后調(diào)用Call對象的invoke方法訪問服務(wù)。

            以下給出了一個客戶端訪問Web服務(wù)的例程——AXISTest.java:

            文件AXISTest.java

          package axisexercise;

          import org.apache.axis.client.Call;

          import org.apache.axis.client.Service;

          import org.apache.axis.encoding.XMLType;

          import javax.xml.rpc.ParameterMode;

          public class AXISTest
          {
              public static void main( String[] args ) throws Exception
              {
                   創(chuàng)建service和call對象,這些對象是標準的JAX-RPC對象,這些對象用于存儲服務(wù)調(diào)用的數(shù)據(jù)(metadata)。

           Service service = new Service();
           Call call = ( Call ) service.createCall();
           //////////訪問即時發(fā)布的Distance服務(wù)

           //設(shè)置訪問點
           call.setTargetEndpointAddress( "http://localhost:8080/axis/Distance.jws" );

           //設(shè)置操作名
           call.setOperationName( "convertMile2Kilometre" );

           //設(shè)置入口參數(shù)
           call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );

           //設(shè)置返回參數(shù)類型
           call.setReturnType( XMLType.XSD_DOUBLE );
           Double d1 = new Double( 190 );

           //調(diào)用服務(wù),在invoke方法中傳入的是包含調(diào)用參數(shù)的數(shù)組
           System.out.println( d1 + " 英里相當(dāng)于 " +
           call.invoke( new Object[] {d1} ) + " 公里!" );

           //////////訪問定制發(fā)布的Capacity服務(wù)
           call = ( Call ) service.createCall();

           //設(shè)置訪問點
           call.setTargetEndpointAddress( "http://localhost:8080/axis/services/Capacity" );

           //設(shè)置操作名
           call.setOperationName( "convertGallon2Litre" );

           //設(shè)置入口參數(shù)
           call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );
           call.setReturnType( XMLType.XSD_DOUBLE );
           d1 = new Double( 10.00 );

           //調(diào)用服務(wù)
           System.out.println( d1 + " 加侖相當(dāng)于 " +
           call.invoke( new Object[] {d1} ) + " 升!" );

              } //main()

          }/* AXISTest */

          編譯運行后運行可以看到以下的結(jié)果:

          190.0英里相當(dāng)于305.71公里!

          10.0加侖相當(dāng)于45.46升!
           
            注意程序在訪問即時發(fā)布的Distance服務(wù)和定制發(fā)布的Capacity服務(wù)時的不同,前者的服務(wù)訪問點地址為http://localhost:8080/axis/HelloWorld.jws,而后者的則為http://localhost:8080/axis/services/Capacity


          八、服務(wù)類型:RPC, Document, Wrapped, and Message
          在Axis中,有四種服務(wù)類型:

          1. RPC服務(wù):
          PRC服務(wù)是AXIS中的默認服務(wù),當(dāng)你通過<service ... provider="java:RPC"> or <service ... style="RPC">標簽進行部署的時候,使用的就是RPC服務(wù)。RPC服務(wù)遵循SOAP RPC和其編碼規(guī)范。AXIS可以將XML反序列化成java對象,并將其傳給服務(wù)的方法。并且可以將服務(wù)的方法返回的JAVA對象序列化成XML。

          2.Document / Wrapped services
          Document services and wrapped services are similar in that neither uses the SOAP encoding for data; it's just plain old XML schema. In both cases, however, Axis still "binds" Java representations to the XML (see the databinding section for more), so you end up dealing with Java objects, not directly with XML constructs.

          Document和Wrapped服務(wù)都不使用SOAP編碼數(shù)據(jù),這一點是他們相似的地方。他們僅僅使用舊的XML模式。然而,在這兩種服務(wù)中,AXIS將捆綁Java的表示到XML文檔中,所以你最終處理的是java對象而不直接處理XML。

          下面是包含定單的一個簡單的SOAP消息,你可以看到Document 和 Wrapped 服務(wù)的區(qū)別所在:
          <soap:Envelope xmlns="http://xml.apache.org/axis/wsdd/"
             xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
            <soap:Body>
           <myNS:PurchaseOrder xmlns:myNS="http://commerce.com/PO">
             <item>SK001</item>
             <quantity>1</quantity>
             <description>Sushi Knife</description>
           </myNS:PurchaseOrder>
            </soap:Body>
          </soap:Envelope>

          相應(yīng)的XML模式如下:

          <schema targetNamespace="http://commerce.com/PO">
            <complexType name="POType">
           <sequence>
             <element name="item" type="xsd:string"/>
             <element name="quantity" type="xsd:int"/>
             <element name="description" type="xsd:string"/>
           </sequence>
            </complexType>
            <element name="PurchaseOrder" type="POType"/>
          </deployment>

          對于Document類型服務(wù),他將映射成下面的方法:
          public void method(PurchaseOrder po)


          八、soap envolop(soap信封)
          1. soap信封
          在客戶端發(fā)出服務(wù)請求以及服務(wù)端返回請求結(jié)果的時候,在網(wǎng)絡(luò)中傳輸?shù)氖荢OAP信封。首先客戶端程序?qū)⒄埱髤?shù)及請求的方法序列到XML的文件中(SOAP信封),并將SOAP信封傳送到服務(wù)器端。服務(wù)器端接受到SOAP信封后,將解析這個SOAP信封并反序列化調(diào)用參數(shù)及方法并將該方法的調(diào)用結(jié)果封裝成SOAP信封(序列到XML的文件中)返回給客戶端,客戶端同樣將SOAP信封中封裝的返回結(jié)果反序列化為想要得到的結(jié)果。

          我們來看下面這段客戶端程序的SOAP信封:
          (1) 客戶端程序:
            import org.apache.axis.client.Call;
            import org.apache.axis.client.Service;
            import javax.xml.namespace.QName;
           
            public class TestClient
            {
               public static void main(String [] args)
               {
                  try
                  {
                       String endpoint = "http://nagoya.apache.org:5049/axis/services/echo";
                       Service  service = new Service();
                       Call  call = (Call) service.createCall();
           
                       call.setTargetEndpointAddress( new java.net.URL(endpoint) );
                       call.setOperationName(new QName("http://soapinterop.org/", "echoString"));
           
                       String ret = (String) call.invoke( new Object[] { "Hello!" } );
           
                       System.out.println("Sent 'Hello!', got '" + ret + "'");
                   }
            catch (Exception e)
            {
                       System.err.println(e.toString());
                   }
               }
            }

          (2) SOAP信封:
          <?xml version="1.0" encoding="UTF-8"?>
          <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SOAP-ENV:Body>
           <ns1:echoString xmlns:ns1="http://soapinterop.org/">
             <arg0 xsi:type="xsd:string">Hello!</arg0>
           </ns1:echoString>
            </SOAP-ENV:Body>
          </SOAP-ENV:Envelope>

          2. 參數(shù)命名:
          在上面的代碼中,AXIS自動將在Soap消息中的函數(shù)調(diào)用參數(shù)命名為arg0,arg1等等,如果你想按照自己定義的參數(shù)名調(diào)用方法的話,很簡單,在你調(diào)用invoke函數(shù)之前只要調(diào)用addParameter()函數(shù)即可。如下所示:

             call.addParameter("testParam",
                org.apache.axis.Constants.XSD_STRING,
                javax.xml.rpc.ParameterMode.IN);
             call.setReturnType(org.apache.axis.Constants.XSD_STRING);
          將testParam定義為調(diào)用函數(shù)的第一個參數(shù)(這里也只有一個參數(shù)),這里也可以同時定義該參數(shù)的類型以及該參數(shù)是輸入、輸出還是輸入輸出類型。在這里它是一個輸入類型,現(xiàn)在當(dāng)你運行程序,你將得到下面的消息:
          <?xml version="1.0" encoding="UTF-8"?>
          <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SOAP-ENV:Body>
           <ns1:echoString xmlns:ns1="http://soapinterop.org/">
             <testParam xsi:type="xsd:string">Hello!</testParam>
           </ns1:echoString>
            </SOAP-ENV:Body>
          </SOAP-ENV:Envelope>

          3. 返回類型
          在上面的代碼中我們知道echoString函數(shù)將返回一個String對象,而且我們也希望通過客戶端的調(diào)用能夠返回預(yù)期的String對象。下面是一個典型的通過調(diào)用echoString函數(shù)后獲得的Soap信封(消息)。
          <?xml version="1.0" encoding="UTF-8"?>
            <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SOAP-ENV:Body>
             <ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/">
           <result xsi:type="xsd:string">Hello!</result>
             </ns1:echoStringResponse>
            </SOAP-ENV:Body>
           </SOAP-ENV:Envelope>
          我們可以看到這里已經(jīng)聲明了返回類型(<result xsi:type="xsd:string">)是一個String對象。這樣Axis就可以將返回結(jié)果反序列化成我們想要的String對象了。
          很多工具都會將這種確定的類型信息放到XML文件中,以生成消息的“自我描述部分”,另一方面,還有一些工具是象下面這樣返回響應(yīng)的:(Many toolkits put this kind of explicit typing information in the XML to make the message "self-describing". On the other hand, some toolkits return responses that look like this:)
          <?xml version="1.0" encoding="UTF-8"?>
          <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
           <SOAP-ENV:Body>
            <ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/">
             <result>Hello, I'm a string!</result>
            </ns1:echoStringResponse>
           </SOAP-ENV:Body>
          </SOAP-ENV:Envelope>
          在這里并沒有返回類型,那么我們怎么知道應(yīng)該將返回結(jié)果反序列化成什么類型的結(jié)果呢?答案是metadata,在這種情況下,我們需要一個描述來指明我們期望的返回類型,下面這行代碼說明了在客戶端應(yīng)該如何去做:
          call.setReturnType( org.apache.axis.Constants.XSD_STRING );
          這個方法將會告訴Axis客戶端,如果返回的結(jié)果沒有指明類型的話,那么Axis將會把返回類型指明為xsi:type屬性所預(yù)定義的SOAP類型,在這里XSD_STRING屬性所指明的是String類型。

          所以也有這樣一個相似的方法,允許你指定所期望返回的Java的類。
          call.setReturnClass(String.class);



          http://blog.csdn.net/tenwang1977/archive/2004/09/06/95991.aspx

          posted on 2007-06-21 16:20 狼愛上貍 閱讀(460) 評論(0)  編輯  收藏 所屬分類: AXIS

          主站蜘蛛池模板: 西安市| 钟祥市| 四子王旗| 凌云县| 精河县| 磴口县| 霞浦县| 涿鹿县| 日照市| 微山县| 保靖县| 德江县| 怀集县| 布拖县| 阳山县| 鹤庆县| 韩城市| 惠东县| 铜陵市| 芜湖市| 外汇| 麻栗坡县| 桃源县| 石首市| 哈巴河县| 汾西县| 富民县| 东乌珠穆沁旗| 子洲县| 浠水县| 固原市| 钟祥市| 屏山县| 女性| 大洼县| 应城市| 凤凰县| 永善县| 嵩明县| 聂荣县| 习水县|