<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Axis2是一套嶄新的WebService引擎,該版本是對Axis1.x重新設(shè)計的產(chǎn)物。Axis2不僅支持SOAP1.1SOAP1.2,還集成了非常流行的REST WebService,同時還支持SpringJSON等技術(shù)。這些都將在后面的系列教程中講解。在本文中主要介紹了如何使用Axis2開發(fā)一個不需要任何配置文件的WebService,并在客戶端使用JavaC#調(diào)用這個WebService

    一、Axis2的下載和安裝

    ??? 讀者可以從如下的網(wǎng)址下載Axis2的最新版本:

    ??? http://ws.apache.org/axis2/

    ??? 在本文使用了目前Axis2的最新版本1.4.1。讀者可以下載如下兩個zip包:

    ??? axis2-1.4.1-bin.zip

    ??? axis2-1.4.1-war.zip

    ??? 其中axis2-1.4.1-bin.zip文件中包含了Axis2中所有的jar文件, axis2-1.4.1-war.zip文件用于將WebService發(fā)布到Web容器中。

    ??? axis2-1.4.1-war.zip文件解壓到相應的目錄,將目錄中的axis2.war文件放到<Tomcat安裝目錄>\webapps目錄中(本文使用的Tomcat的版本是6.x),并啟動Tomcat

    ??? 在瀏覽器地址欄中輸入如下的URL

    ??? http://localhost:8080/axis2/

    ??? 如果在瀏覽器中顯示出如圖1所示的頁面,則表示Axis2安裝成功。



    圖1

    二、編寫和發(fā)布WebService

    ??對于用Java實現(xiàn)的服務程序給人的印象就是需要進行大量的配置,不過這一點在Axis2中將被終結(jié)。在Axis2中不需要進行任何的配置,就可以直接將一個簡單的POJO發(fā)布成WebService。其中POJO中所有的public方法將被發(fā)布成WebService方法。

    ??? 下面我們來實現(xiàn)一個簡單的POJO,代碼如下:

    public?class?SimpleService
    {
    ????
    public?String?getGreeting(String?name)
    ????{
    ????????
    return?"你好?"?+?name;
    ????}????
    ????
    public?int?getPrice()
    ????{
    ????????
    return?new?java.util.Random().nextInt(1000);
    ????}????
    }

    ??? SimpleService類中有兩個方法,由于這兩個方法都是public方法,因此,它們都將作為WebService方法被發(fā)布。

    ??? 編譯SimpleService類后,將SimpleService.class文件放到<Tomcat安裝目錄>\webapps\axis2\WEB-INF\pojo目錄中(如果沒有pojo目錄,則建立該目錄)。現(xiàn)在我們已經(jīng)成功將SimpleService類發(fā)布成了WebService。在瀏覽器地址欄中輸入如下的URL

    http://localhost:8080/axis2/services/listServices

    ??? 這時當前頁面將顯示所有在Axis2中發(fā)布的WebService,如圖2所示。



    圖2

    ??? 在瀏覽器地址欄中輸入如下的兩個URL來分別測試getGreetinggetPrice方法:

    http://localhost:8080/axis2/services/SimpleService/getGreeting?name=bill

    http://localhost:8080/axis2/services/SimpleService/getPrice

    ??? 3和圖4分別顯示了getGreetinggetPrice方法的測試結(jié)果。

    圖3? getGreeting方法的測試結(jié)果

    圖4? getPrice方法的測試結(jié)果

    ??? 在編寫、發(fā)布和測試0配置的WebService時應注意如下幾點:

    ??? 1.?POJO類不能使用package關(guān)鍵字聲明包。

    ??? 2.?Axis2在默認情況下可以熱發(fā)布WebService,也就是說,將WebService.class文件復制到pojo目錄中時,Tomcat不需要重新啟動就可以自動發(fā)布WebService。如果想取消Axis2的熱發(fā)布功能,可以打開<Tomcat安裝目錄>\webapps\axis2\WEB-INF\conf\axis2.xml,找到如下的配置代碼:

    <parameter?name="hotdeployment">true</parameter>

    ??? true改為false即可。要注意的是,Axis2在默認情況下雖然是熱發(fā)布,但并不是熱更新,也就是說,一旦成功發(fā)布了WebService,再想更新該WebService,就必須重啟Tomcat。這對于開發(fā)人員調(diào)試WebService非常不方便,因此,在開發(fā)WebService時,可以將Axis2設(shè)為熱更新。在axis2.xml文件中找到<parameter name="hotupdate">false</parameter>,將false改為true即可。

    ??? 3.?在瀏覽器中測試WebService時,如果WebService方法有參數(shù),需要使用URL的請求參數(shù)來指定該WebService方法參數(shù)的值,請求參數(shù)名與方法參數(shù)名要一致,例如,要測試getGreeting方法,請求參數(shù)名應為name,如上面的URL所示。

    ??? 4.?發(fā)布WebServicepojo目錄只是默認的,如果讀者想在其他的目錄發(fā)布WebService,可以打開axis2.xml文件,并在<axisconfig>元素中添加如下的子元素:

    ????<deployer?extension=".class"?directory="my"?class="org.apache.axis2.deployment.POJODeployer"/>

    ??? 上面的配置允許在<Tomcat安裝目錄>"webapps"axis2"WEB-INF"my目錄中發(fā)布WebService。例如,將本例中的SimpleService.class復制到my目錄中也可以成功發(fā)布(但要刪除pojo目錄中的SimpleService.class,否則WebService會重名)。

    三、Java實現(xiàn)調(diào)用WebService的客戶端程序

    ??? WebService是為程序服務的,只在瀏覽器中訪問WebService是沒有意義的。因此,在本節(jié)使用Java實現(xiàn)了一個控制臺程序來調(diào)用上一節(jié)發(fā)布的WebService。調(diào)用WebService的客戶端代碼如下:

    package?client;

    import?javax.xml.namespace.QName;
    import?org.apache.axis2.addressing.EndpointReference;
    import?org.apache.axis2.client.Options;
    import?org.apache.axis2.rpc.client.RPCServiceClient;

    public?class?RPCClient
    {
    ????
    public?static?void?main(String[]?args)?throws?Exception??
    ????{
    ????????
    //??使用RPC方式調(diào)用WebService????????
    ????????RPCServiceClient?serviceClient?=?new?RPCServiceClient();
    ????????Options?options?
    =?serviceClient.getOptions();
    ????????
    //??指定調(diào)用WebService的URL
    ????????EndpointReference?targetEPR?=?new?EndpointReference(
    ????????????????
    "http://localhost:8080/axis2/services/SimpleService");
    ????????options.setTo(targetEPR);
    ????????
    //??指定getGreeting方法的參數(shù)值
    ????????Object[]?opAddEntryArgs?=?new?Object[]?{"超人"};
    ????????
    //??指定getGreeting方法返回值的數(shù)據(jù)類型的Class對象
    ????????Class[]?classes?=?new?Class[]?{String.class};
    ????????
    //??指定要調(diào)用的getGreeting方法及WSDL文件的命名空間
    ????????QName?opAddEntry?=?new?QName("http://ws.apache.org/axis2",?"getGreeting");
    ????????
    //??調(diào)用getGreeting方法并輸出該方法的返回值
    ????????System.out.println(serviceClient.invokeBlocking(opAddEntry,?opAddEntryArgs,?classes)[0]);
    ????????
    //??下面是調(diào)用getPrice方法的代碼,這些代碼與調(diào)用getGreeting方法的代碼類似
    ????????classes?=?new?Class[]?{int.class};
    ????????opAddEntry?
    =?new?QName("http://ws.apache.org/axis2",?"getPrice");
    ????????System.out.println(serviceClient.invokeBlocking(opAddEntry,?
    new?Object[]{},?classes)[0]);
    ????}?
    }

    運行上面的程序后,將在控制臺輸出如下的信息:
    你好?超人
    443

    ??? 在編寫客戶端代碼時應注意如下幾點:

    ??? 1.?客戶端代碼需要引用很多Axis2jar包,如果讀者不太清楚要引用哪個jar包,可以在Eclipse的工程中引用Axis2發(fā)行包的lib目錄中的所有jar包。

    ??? 2.?在本例中使用了RPCServiceClient類的invokeBlocking方法調(diào)用了WebService中的方法。invokeBlocking方法有三個參數(shù),其中第一個參數(shù)的類型是QName對象,表示要調(diào)用的方法名;第二個參數(shù)表示要調(diào)用的WebService方法的參數(shù)值,參數(shù)類型為Object[];第三個參數(shù)表示WebService方法的返回值類型的Class對象,參數(shù)類型為Class[]。當方法沒有參數(shù)時,invokeBlocking方法的第二個參數(shù)值不能是null,而要使用new Object[]{}

    ??? 3.?如果被調(diào)用的WebService方法沒有返回值,應使用RPCServiceClient類的invokeRobust方法,該方法只有兩個參數(shù),它們的含義與invokeBlocking方法的前兩個參數(shù)的含義相同。

    ??? 4.?在創(chuàng)建QName對象時,QName類的構(gòu)造方法的第一個參數(shù)表示WSDL文件的命名空間名,也就是<wsdl:definitions>元素的targetNamespace屬性值,下面是SimpleService類生成的WSDL文件的代碼片段:

    <?xml?version="1.0"?encoding="UTF-8"?>
    <wsdl:definitions?xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"?xmlns:ns1="http://org.apache.axis2/xsd"
    xmlns:ns
    ="http://ws.apache.org/axis2"?xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
    xmlns:http
    ="http://schemas.xmlsoap.org/wsdl/http/"?xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mime
    ="http://schemas.xmlsoap.org/wsdl/mime/"?xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soap12
    ="http://schemas.xmlsoap.org/wsdl/soap12/"
    targetNamespace
    ="http://ws.apache.org/axis2"
    >
    ????
    <wsdl:types>
    ?????????
    ????
    </wsdl:types>
    ?????
    </wsdl:definitions>

    四、用wsdl2java簡化客戶端的編寫

    ??? 也許有很多讀者會說“有沒有搞錯啊,只調(diào)用兩個WebService方法用要寫這么多代碼,太麻煩了”。

    ??? 不過幸好Axis2提供了一個wsdl2java.bat命令可以根據(jù)WSDL文件自動產(chǎn)生調(diào)用WebService的代碼。wsdl2java.bat命令可以在<Axis2安裝目錄>"bin目錄中找到。在使用wsdl2java.bat命令之前需要設(shè)置AXIS2_HOME環(huán)境變量,該變量值是<Axis2安裝目錄>

    ??? Windows控制臺輸出如下的命令行來生成調(diào)用WebService的代碼:

    %AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/SimpleService?wsdl -p client -s -o stub

    ??? 其中-url參數(shù)指定了wsdl文件的路徑,可以是本地路徑,也可以是網(wǎng)絡(luò)路徑。-p參數(shù)指定了生成的Java類的包名,-o參數(shù)指定了生成的一系列文件保存的根目錄。在執(zhí)行完上面的命令后,讀者就會發(fā)現(xiàn)在當前目錄下多了個stub目錄,在."stub"src"client目錄可以找到一個SimpleServiceStub.java文件,該文件復雜調(diào)用WebService,讀者可以在程序中直接使用這個類,代碼如下:

    package?client;

    import?javax.xml.namespace.QName;
    import?org.apache.axis2.addressing.EndpointReference;
    import?org.apache.axis2.client.Options;
    import?org.apache.axis2.rpc.client.RPCServiceClient;

    public?class?StubClient
    {
    ????
    public?static?void?main(String[]?args)?throws?Exception??
    ????{
    ????????SimpleServiceStub?stub?
    =?new?SimpleServiceStub();
    ????????SimpleServiceStub.GetGreeting?gg?
    =?new?SimpleServiceStub.GetGreeting();
    ????????gg.setName(
    "比爾");
    ????????System.out.println(?stub.getGreeting(gg).get_return());
    ????????System.out.println(stub.getPrice().get_return());
    ????}?
    }

    ??? 上面的代碼大大簡化了調(diào)用WebService的步驟,并使代碼更加簡潔。但要注意的是,wsdl2java.bat命令生成的Stub類將WebService方法的參數(shù)都封裝在了相應的類中,類名為方法名,例如,getGreeting方法的參數(shù)都封裝在了GetGreeting類中,要想調(diào)用getGreeting方法,必須先創(chuàng)建GetGreeting類的對象實例。

    五、使用C#調(diào)用WebService

    ??? 從理論上說,WebService可以被任何支持SOAP協(xié)議的語言調(diào)用。在Visual Studio中使用C#調(diào)用WebService是在所有語言中最容易實現(xiàn)的(VB.net的調(diào)用方法類似,也同樣很簡單)。

    ??? 新建一個Visual Studio工程,并在引用Web服務的對話框中輸入如下的URL,并輸入Web引用名為“WebService”:

    ??? http://localhost:8080/axis2/services/SimpleService?wsdl

    ??? 然后引用Web服務的對話框就會顯示該WebService中的所有的方法,如圖5所示。



    圖5

    ??? 在完成上面的工作后,只需要如下三行C#代碼就可以調(diào)用getGreetinggetPrice方法,并顯示這兩個方法的返回值:

    WebService.SimpleService?simpleService?=?new?WSC.WebService.SimpleService();
    MessageBox.Show(?simpleService.getGreeting(
    "比爾"));
    MessageBox.Show(simpleService.getPrice().@return.ToString());

    ??? .net解析WSDL文件時直接將getGreeting方法的參數(shù)映射為String類型,因此,可以直接進行傳值。
    ??? 從上面的調(diào)用過程可以看出,添加Web引用的過程就相當于在Java中調(diào)用wsdl2java.bat自動生成stub類的過程。只是在調(diào)用stub類時與C#有一定的區(qū)別,但從總體上來說,都大大簡化了調(diào)用WebService的過程。

    posted @ 2009-02-23 17:37 zhuyongjp 閱讀(922) | 評論 (0)編輯 收藏
     

    接口 interface

    import ?J2EE技術(shù)的爬蟲.util.Collection;
    import ?J2EE技術(shù)的爬蟲.util.List;

    public ? interface ?IMathService? {
    ?
    /**
    ??*?加
    ??*?
    @param ?a
    ??*?
    @param ?b
    ??*?
    @return
    ??
    */

    ?
    public ? int ?add( int ?a, int ?b);
    ?
    /**
    ??*?減
    ??*?
    @param ?a
    ??*?
    @param ?b
    ??*?
    @return
    ??
    */

    ?
    public ? int ?sub( int ?a, int ?b);
    /**
    上傳二進制文件
    */

    ??
    public ?String?sendFile(String?fileName, byte []?file?);
    ?
    }



    實現(xiàn) implements

    import ?J2EE技術(shù)的爬蟲.io.File;
    import ?J2EE技術(shù)的爬蟲.io.FileOutputStream;
    import ?J2EE技術(shù)的爬蟲.sql.Connection;
    import ?J2EE技術(shù)的爬蟲.sql.ResultSet;
    import ?J2EE技術(shù)的爬蟲.sql.Statement;
    import ?J2EE技術(shù)的爬蟲.util.ArrayList;
    import ?J2EE技術(shù)的爬蟲.util.Collection;
    import ?J2EE技術(shù)的爬蟲.util.List;

    import ?com.newsoft.oa.bean.User;
    import ?com.newsoft.oa.uitl.Connector;
    import ?com.thoughtworks.xstream.XStream;

    public ? class ?MathServiceImpl? implements ?IMathService {
    ??
    public ? int ?add( int ?a, int ?b) {
    ???
    return ?a + b;
    ??}

    ??
    ??
    public ? int ?sub( int ?a, int ?b) {
    ???
    return ?a - b;
    ??}
    ?
    ??
    public ?String?getWelComeStr(String?name) {
    ???
    return ? " hi? " + name + " !?歡迎你 " ;
    ??}

    ??
    public ?List?getUsers() {
    ???List?l
    = new ?ArrayList();
    ???l.add(
    " name " );
    ???l.add(
    " password " );
    ???l.add(
    " sex " );
    ???
    return ?l;
    ??}


    public ?String?sendFile(String?fileName,? byte []?filebytes)? {
    ?
    try {
    ??String?path
    = "" ;
    ???
    if (filebytes != null && filebytes.length > 0 ) {
    ????File?file
    = new ?File( " / " + fileName);
    ????
    ????file.createNewFile();
    ????FileOutputStream?fos
    = new ?FileOutputStream(file);
    ????fos.write(filebytes);
    ????fos.close();
    ????path
    = file.getAbsolutePath();
    ????System.out.println(path);
    ????
    ????file
    = null ;
    ????
    ???}

    ???
    ???
    return ?path;
    ?}
    catch (Exception?ex) {
    ??
    return ? " false " ;
    ?}

    }



    }



    ?


    配置文件

    放在 Classes/META-INF/xfire/service.xml;里面

    <? xml?version="1.0"?encoding="UTF-8" ?>
    < beans? xmlns ="http://xfire.codehaus.org/config/1.0" >
    ?
    < service >
    ??
    < name > MathService </ name >
    ??
    < namespace > newsoft/oa/MathService </ namespace >
    ??
    < serviceClass >
    ???com.newsoft.oa.services.IMathService
    ??
    </ serviceClass >
    ??
    < implementationClass >
    ???com.newsoft.oa.services.MathServiceImpl
    ??
    </ implementationClass >

    ?
    </ service >
    </ beans >


    其實是借鑒了Spring的寫法,用過Spring不會對著陌生,(Application-context.xml)

    WEB-XML加上

    < servlet >
    ??
    < servlet-name > XFireServlet </ servlet-name >
    ??
    < servlet-class >
    ???org.codehaus.xfire.transport.http.XFireConfigurableServlet
    ??
    </ servlet-class >
    ?
    </ servlet >

    ?
    < servlet-mapping >
    ??
    < servlet-name > XFireServlet </ servlet-name >
    ??
    < url-pattern > /servlet/XFireServlet/* </ url-pattern >
    ?
    </ servlet-mapping >

    ?
    < servlet-mapping >
    ??
    < servlet-name > XFireServlet </ servlet-name >
    ??
    < url-pattern > /services/* </ url-pattern >
    ?
    </ servlet-mapping >


    最后就是客戶端了

    /?/Create?a?metadata?of?the?service??????????????
    ?Service?serviceModel?
    =?new?ObjectServiceFactory().create(IMathService.class);?
    //?Create?a?proxy?for?the?deployed?service??????
    ??
    ?XFireProxyFactory?factory?
    =?new?XFireProxyFactory(XFireFactory.newInstance().getXFire());???
    ?String?serviceUrl?
    =?"http://localhost:8080/ws/services/MathService";
    ??client?
    =?null;???????
    ?
    try?{??????????
    ???client?
    =?(IMathService)?factory.create(serviceModel,?serviceUrl);??
    ???File?file
    =new?File("c:\\SUPERMAP?白皮書.pdf");
    ???FileInputStream?fis
    =new?FileInputStream(file);
    ???
    byte[]?b=new?byte[fis.available()];
    ???fis.read(b);
    ??System.out.println(client.sendFile(file.getName(),?b));
    ?}
    ?catch?(Exception?ex)?{?????????
    ???ex.printStackTrace();
    ?}
    ???????????????????????????//Invoke?the?service????
    ?int?serviceResponse?=?0;
    ?
    int?a=10,b=20;

    就是

    Service serviceModel = new ObjectServiceFactory().create(IMathService.class);?
    ?XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire());??
    ?String serviceUrl = http://localhost:8080/ws/services/MathService;

    三行字建立連接請求,

    太輕松了

    傳輸文件速度也可以,二進制,2M多的文件,也能輕松傳遞

    用.net和delphi平臺測試,兼容性沒問題(按道理 soap,也不應該有問題)

    這是為客戶搭建的在 檔案系統(tǒng)和OA審批間作文件歸檔的嘗試項目

    哈,完整的項目代碼,就不方便講了。
    posted @ 2009-02-20 15:07 zhuyongjp 閱讀(724) | 評論 (0)編輯 收藏
     
    我們項目的整個架構(gòu)使用的比較流行的WSH MVC組合,即webwork2 + Spring + Hibernate;
    1.首先集成Apacha CXF WebService 到 Spring 框架中;
    ?? apache cxf 下載地址:http://people.apache.org/dist/incubator/cxf/2.0.4-incubator/apache-cxf-2.0.4-incubator.zip
    ? 在spring context配置文件中引入以下cxf配置
    ?? Xml代碼
    <import?resource="classpath*:META-INF/cxf/cxf.xml"?/>??
    <import?resource="classpath*:META-INF/cxf/cxf-extension-soap.xml"?/>??
    <import?resource="classpath*:META-INF/cxf/cxf-servlet.xml"?/>??

    在web.xml中添加過濾器:
    ?? Xml代碼

    2.開發(fā)服務端WebService接口:
    ??? Java代碼
    1. /** ?
    2. ?*?WebService接口定義類. ?
    3. ?*? ?
    4. ?*?使用@WebService將接口中的所有方法輸出為Web?Service. ?
    5. ?*?可用annotation對設(shè)置方法、參數(shù)和返回值在WSDL中的定義. ?
    6. ?*/??
    7. @WebService??
    8. public?interface?WebServiceSample?{ ??
    9. ??
    10. ??
    11. ????/** ?
    12. ?????*?一個簡單的方法,返回一個字符串 ?
    13. ?????*?@param?hello ?
    14. ?????*?@return ?
    15. ?????*/??
    16. ????String?say(String?hello); ??
    17. ???? ??
    18. ????/** ?
    19. ?????*?稍微復雜一些的方法,傳遞一個對象給服務端處理 ?
    20. ?????*?@param?user ?
    21. ?????*?@return ?
    22. ?????*/??
    23. ????String?sayUserName( ??
    24. ????????????@WebParam(name?=?"user")? ??
    25. ????????????UserDTO?user); ??
    26. ???? ??
    27. ????/** ?
    28. ?????*?最復雜的方法,返回一個List封裝的對象集合 ?
    29. ?????*?@return ?
    30. ?????*/??
    31. ????public? ??
    32. ????@WebResult(partName="o") ??
    33. ????ListObject?findUsers(); ??
    34. ??
    35. }??

    ?? 由簡單到復雜定義了三個接口,模擬業(yè)務需求;

    3.實現(xiàn)接口

    ?? Java代碼
    1. /** ?
    2. ?*?WebService實現(xiàn)類. ?
    3. ?*? ?
    4. ?*?使用@WebService指向Interface定義類即可. ?
    5. ?*/??
    6. @WebService(endpointInterface?=?"cn.org.coral.biz.examples.webservice.WebServiceSample") ??
    7. public?class?WebServiceSampleImpl?implements?WebServiceSample?{ ??
    8. ??
    9. ????public?String?sayUserName(UserDTO?user)?{ ??
    10. ????????return?"hello?"+user.getName(); ??
    11. ????} ??
    12. ??
    13. ????public?String?say(String?hello)?{ ??
    14. ????????return?"hello?"+hello; ??
    15. ????} ??
    16. ??
    17. ????public?ListObject?findUsers()?{ ??
    18. ????????ArrayList<Object>?list?=?new?ArrayList<Object>(); ??
    19. ???????? ??
    20. ????????list.add(instancUser(1,"lib")); ??
    21. ????????list.add(instancUser(2,"mld")); ??
    22. ????????list.add(instancUser(3,"lq")); ??
    23. ????????list.add(instancUser(4,"gj")); ??
    24. ????????ListObject?o?=?new?ListObject(); ??
    25. ????????o.setList(list); ??
    26. ????????return?o; ??
    27. ????} ??
    28. ???? ??
    29. ????private?UserDTO?instancUser(Integer?id,String?name){ ??
    30. ????????UserDTO?user?=?new?UserDTO(); ??
    31. ????????user.setId(id); ??
    32. ????????user.setName(name); ??
    33. ????????return?user; ??
    34. ????} ??
    35. }??

    ?4.依賴的兩個類:用戶對象與List對象
    ???? Java代碼

    1. /** ?
    2. ?*?Web?Service傳輸User信息的DTO. ?
    3. ?*? ?
    4. ?*?分離entity類與web?service接口間的耦合,隔絕entity類的修改對接口的影響. ?
    5. ?*?使用JAXB?2.0的annotation標注JAVA-XML映射,盡量使用默認約定. ?
    6. ?*? ?
    7. ?*/??
    8. @XmlAccessorType(XmlAccessType.FIELD) ??
    9. @XmlType(name?=?"User") ??
    10. public?class?UserDTO?{ ??
    11. ??
    12. ????protected?Integer?id; ??
    13. ??
    14. ????protected?String?name; ??
    15. ??
    16. ????public?Integer?getId()?{ ??
    17. ????????return?id; ??
    18. ????} ??
    19. ??
    20. ????public?void?setId(Integer?value)?{ ??
    21. ????????id?=?value; ??
    22. ????} ??
    23. ??
    24. ????public?String?getName()?{ ??
    25. ????????return?name; ??
    26. ????} ??
    27. ??
    28. ????public?void?setName(String?value)?{ ??
    29. ????????name?=?value; ??
    30. ????} ??
    31. }??

    ?? 關(guān)于List對象,參照了有關(guān)JWS的一個問題中的描述:DK6.0 自帶的WebService中 WebMethod的參數(shù)好像不能是ArrayList 或者其他List
    傳遞List需要將List 包裝在其他對象內(nèi)部才行 (個人理解 如有不對請指出) ,我在實踐中也遇到了此類問題.通過以下封裝的對象即可以傳遞List對象.

    Java代碼
    1. /** ?
    2. ?*?<p>Java?class?for?listObject?complex?type. ?
    3. ?*? ?
    4. ?*?<p>The?following?schema?fragment?specifies?the?expected?content?contained?within?this?class. ?
    5. ?*? ?
    6. ?*?<pre> ?
    7. ?*?<complexType?name="listObject"> ?
    8. ?*???<complexContent> ?
    9. ?*?????<restriction?base="{http://www.w3.org/2001/XMLSchema}anyType"> ?
    10. ?*???????<sequence> ?
    11. ?*?????????<element?name="list"?type="{http://www.w3.org/2001/XMLSchema}anyType"?maxOccurs="unbounded"?minOccurs="0"/> ?
    12. ?*???????</sequence> ?
    13. ?*?????</restriction> ?
    14. ?*???</complexContent> ?
    15. ?*?</complexType> ?
    16. ?*?</pre> ?
    17. ?*? ?
    18. ?*? ?
    19. ?*/??
    20. @XmlAccessorType(XmlAccessType.FIELD) ??
    21. @XmlType(name?=?"listObject",?propOrder?=?{?"list"?}) ??
    22. public?class?ListObject?{ ??
    23. ??
    24. ????@XmlElement(nillable?=?true) ??
    25. ????protected?List<Object>?list; ??
    26. ??
    27. ????/** ?
    28. ?????*?Gets?the?value?of?the?list?property. ?
    29. ?????*? ?
    30. ?????*?<p> ?
    31. ?????*?This?accessor?method?returns?a?reference?to?the?live?list, ?
    32. ?????*?not?a?snapshot.?Therefore?any?modification?you?make?to?the ?
    33. ?????*?returned?list?will?be?present?inside?the?JAXB?object. ?
    34. ?????*?This?is?why?there?is?not?a?<CODE>set</CODE>?method?for?the?list?property. ?
    35. ?????*? ?
    36. ?????*?<p> ?
    37. ?????*?For?example,?to?add?a?new?item,?do?as?follows: ?
    38. ?????*?<pre> ?
    39. ?????*????getList().add(newItem); ?
    40. ?????*?</pre> ?
    41. ?????*? ?
    42. ?????*? ?
    43. ?????*?<p> ?
    44. ?????*?Objects?of?the?following?type(s)?are?allowed?in?the?list ?
    45. ?????*?{@link?Object?} ?
    46. ?????*? ?
    47. ?????*? ?
    48. ?????*/??
    49. ????public?List<Object>?getList()?{ ??
    50. ????????if?(list?==?null)?{ ??
    51. ????????????list?=?new?ArrayList<Object>(); ??
    52. ????????} ??
    53. ????????return?this.list; ??
    54. ????} ??
    55. ??
    56. ????public?void?setList(ArrayList<Object>?list)?{ ??
    57. ????????this.list?=?list; ??
    58. ????} ??
    59. ??
    60. }??

    5.WebService 服務端 spring 配置文件 ws-context.xml
    Xml代碼
    1. <beans?xmlns="http://www.springframework.org/schema/beans"??
    2. ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
    3. ????xmlns:jaxws="http://cxf.apache.org/jaxws"??
    4. ????xsi:schemaLocation="http://cxf.apache.org/jaxws?http://cxf.apache.org/schemas/jaxws.xsd?http://www.springframework.org/schema/beans??http://www.springframework.org/schema/beans/spring-beans.xsd"??
    5. ????default-autowire="byName"?default-lazy-init="true">??
    6. ???? ??
    7. ????<jaxws:endpoint?id="webServiceSample"??
    8. ????????address="/WebServiceSample"?implementor="cn.org.coral.biz.examples.webservice.WebServiceSampleImpl"/>??
    9. ??
    10. </beans>??

    WebService 客戶端 spring 配置文件 wsclient-context.xml

    Xml代碼
    1. <beans?xmlns="http://www.springframework.org/schema/beans"??
    2. ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
    3. ????xmlns:jaxws="http://cxf.apache.org/jaxws"??
    4. ????xsi:schemaLocation="http://cxf.apache.org/jaxws?http://cxf.apache.org/schemas/jaxws.xsd?http://www.springframework.org/schema/beans??http://www.springframework.org/schema/beans/spring-beans.xsd"??
    5. ????default-autowire="byName"?default-lazy-init="true">??
    6. ??
    7. ????<!--?ws?client?-->??
    8. ????<bean?id="identityValidateServiceClient"?class="cn.org.coral.admin.service.IdentityValidateService"??
    9. ????????factory-bean="identityValidateServiceClientFactory"?factory-method="create"?/>??
    10. ??
    11. ????<bean?id="identityValidateServiceClientFactory"??
    12. ????????class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">??
    13. ????????<property?name="serviceClass"??
    14. ????????????value="cn.org.coral.admin.service.IdentityValidateService"?/>??
    15. ????????<property?name="address"??
    16. ????????????value="http://88.148.29.54:8080/coral/services/IdentityValidateService"/>??
    17. ????</bean>??
    18. ???? ??
    19. </beans>??
    6.發(fā)布到tomcat服務器以后通過以下地址即可查看自定義的webservice接口生成的wsdl:
    http://88.148.29.54:8080/aio/services/WebServiceSample?wsdl

    7.調(diào)用WebService接口的Junit單元測試程序
    Java代碼
    1. package?test.coral.sample; ??
    2. ??
    3. import?org.springframework.test.AbstractDependencyInjectionSpringContextTests; ??
    4. ??
    5. import?cn.org.coral.biz.examples.webservice.WebServiceSample; ??
    6. import?cn.org.coral.biz.examples.webservice.dto.UserDTO; ??
    7. ??
    8. public?class?TestWebServiceSample?extends??
    9. ????????AbstractDependencyInjectionSpringContextTests?{ ??
    10. ????WebServiceSample?webServiceSampleClient; ??
    11. ??
    12. ????public?void?setWebServiceSampleClient(WebServiceSample?webServiceSampleClient)?{ ??
    13. ????????this.webServiceSampleClient?=?webServiceSampleClient; ??
    14. ????} ??
    15. ???? ??
    16. ????@Override??
    17. ????protected?String[]?getConfigLocations()?{ ??
    18. ????????setAutowireMode(AUTOWIRE_BY_NAME); ??
    19. ??????????????????//spring?客戶端配置文件保存位置 ??
    20. ????????return?new?String[]?{?"classpath:/cn/org/coral/biz/examples/webservice/wsclient-context.xml"?}; ??
    21. ????} ??
    22. ???? ??
    23. ????public?void?testWSClinet(){ ??
    24. ????????Assert.hasText(webServiceSampleClient.say("?world")); ??
    25. ????} ??
    26. }??
    posted @ 2009-02-20 13:41 zhuyongjp 閱讀(1449) | 評論 (0)編輯 收藏
     
         摘要: 本文是一個由四篇文章組成的系列的第三篇(請參閱 參考資料),本系列文章旨在介紹創(chuàng)建、描述和發(fā)布 Web 服務的過程。在第一部分中,我借助 WSDL 編制示例講解了如何描述一個 Web 服務。在第二部分中,我討論了 SOAP 的體系結(jié)構(gòu)及其語義。在本文中,我將看一看與 SOAP 相關(guān)的互操作性問題。 Web 服務模型將整個 B2B 領(lǐng)域分成三個步驟或三個域:描述一個服務、將該服務與具體的實現(xiàn)綁定,然...  閱讀全文
    posted @ 2009-02-19 10:44 zhuyongjp 閱讀(422) | 評論 (0)編輯 收藏
     
         摘要: SOAP 和 WSDL 我在本系列文章的 第 1 部分介紹了 WSDL。WSDL 描述了 Web 服務的接口。Web 服務所有者將用 SOAP 來實現(xiàn)他們的接口。因此, WSDL 服務實際上作為 SOAP 服務一樣存在。一旦 Web 服務用戶擁有 WSDL 文件,他或者她就知曉接口的細節(jié)。他或者她就會用 SOAP 來與 Web 服務通信。 可以把 Web 服務考慮為對象,可以通過 WSDL 接口公...  閱讀全文
    posted @ 2009-02-19 10:24 zhuyongjp 閱讀(1458) | 評論 (0)編輯 收藏
     
    可互操作的基于 Web 分布式應用程序的思想并非新近出現(xiàn)。僅舉一例,電子數(shù)據(jù)交換(EDI)市場需求早在 B2B 在線電子商務獲得任何有意義的實現(xiàn)之前就存在了 ― 并且隨著 B2B 電子市場的普及,互操作性已經(jīng)成為最迫切的 EDI 需求。

    以任何在線電子市場為例。存在著許多企業(yè),各自提供特有的“服務( services )”(讓我們稱之為“Web 服務( Web services )”)。在當今的電子商務中,尚不存在一種機制,使一個業(yè)務能自動發(fā)現(xiàn)其預期伙伴提供的服務。所謂的 下一代 .com還是提供這種自動的發(fā)現(xiàn)機制。

    什么是 WSDL?

    這種新的 .com 需要一種解決方案來描述它所提供的服務(Web 服務)。具體而言,這意味著您需要一種格式或某種類型的語法,使您可以通過使用它們來描述下列問題的答案:

    您的在線業(yè)務提供什么服務?
    您如何調(diào)用業(yè)務服務?
    當用戶調(diào)用您的業(yè)務服務時,該業(yè)務服務需要他/她提供什么信息?
    用戶將如何提供這些必需信息?
    服務將以什么格式發(fā)送返回給用戶的信息?
    很幸運,WSDL 提供了完成所有這些作業(yè)的機制。



    WSDL 和 SOAP

    為更好理解 WSDL 是如何工作的,我將首先描述 SOAP 和 HTTP 是如何使用 WSDL 工作的。WSDL 的用途是“描述”您的 Web 服務。業(yè)務之間將通過交換 WSDL 文件來理解對方的服務。一旦知道您伙伴的服務并希望調(diào)用它們,SOAP 就派上用場了。可以將服務看作是通過 SOAP 訪問的對象。

    最有可能的情況是,您將通過因特網(wǎng)或電子郵件與潛在伙伴通信。當然,因特網(wǎng)使用 HTTP 而電子郵件以 SMTP 方式工作,這使得 HTTP 和 SMTP 成為作為 SOAP 的“傳輸服務提供者”的有利候選人。



    WSDL 編寫

    現(xiàn)在,我將講述為 Web 服務編寫 WSDL 的過程。目的是公開現(xiàn)有的 Web 服務。您所處的情況也許就是下列情況之一:

    您有一個現(xiàn)存的服務(例如,一個網(wǎng)站),并希望表示它的功能性。
    您有一個 WSDL,并且希望依照已經(jīng)決定表示的功能性來實現(xiàn) Web服務器端的邏輯。(有些人也許會認為這是一個不可能的方案,但是 UDDI 的指紋概念使它變得極為可能;我將在本系列的第四部分討論 UDDI)。
    您正在從零開始,并且既無網(wǎng)站又無 WSDL 界面。
    本文中所涵蓋的信息適用于這些可能性中的任意一種或全部。

    WSDL 編寫的四個步驟

    我將把 WSDL 編寫分成四個簡單步驟。遵循每個步驟,您的 Web 服務將準備就緒用于部署。

    步驟 1:服務接口

    您將構(gòu)建一個移動電話銷售公司的服務接口作為樣本項目(我將這個服務稱為 MobilePhoneService )。該公司銷售不同型號的移動電話,所以公司 Web 服務的后端數(shù)據(jù)存儲庫中將包含一個具有兩列( model number 和 price )的表格。(為了將焦點保持在 WSDL 本身,我保持該表格的簡單性)。有兩個關(guān)于要使用 WSDL 表示的服務的方法:

    getListOfModels ()
    getPrice (modelNumber)
    GetListOfModels 方法提供了一個字符串數(shù)組,其中每個字符串表示一種移動電話的型號。 GetPrice 獲得型號,然后返回它的價格。WSDL 將這些方法作為操作調(diào)用。現(xiàn)在將開始構(gòu)建“WSDL 接口文件( WSDL interface file )”。

    每個 WSDL 文件的根元素都是 <definitions> ,必須在其中提供服務的完整描述。首先,必須在 <definitions> 元素中提供各種名稱空間的聲明。三個必須做的外部名稱空間聲明是 WSDL、SOAP 和 XSD(XML 模式定義)。還有一個名稱空間 ― TNS,它指您的 MobilePhoneService(這表示 TNS(targetNamespace 的縮寫)包含專為 MobilePhoneService 定義的所有元素和屬性的名稱)。但是 WSDL 是您將在 WSDL 編寫中使用得最多的主要名稱空間。在本系列文章中使用到其它名稱空間時,我將提到它們的效用。

    關(guān)于名稱空間只要注意一點:WSDL 廣泛地使用名稱空間這一概念。我鼓勵您到 W3C 的官方網(wǎng)站去學習關(guān)于名稱空間的更多知識(請參閱 參考資料)。WSDL 是這種思想的一種實現(xiàn),因為名稱空間提供了無限的靈活性,而這恰恰是用于電子數(shù)據(jù)交換的可移植格式所需要的。

    <definitions> 元素包含一個或多個 <portType> 元素,實際上,每個元素都是您希望表示的一系列 operation 。或者,您也可以將單個 portType 元素看作是將各種方法組成類的一個邏輯分組。例如,如果您的供應鏈管理解決方案需要在客戶和供應商之間進行交互,您最可能做的是分別定義與他們交互的功能性;也就是說,您將為用戶和供應商各定義一個 portType。應該將每個 portType 稱為 服務,因此整個 WSDL 文件將成為一個服務集合。

    必須為每個服務提供一個名稱。在本例中,僅有一個服務(因此只有一個 <portType> )。 需要使用該 portType 元素的 name 屬性為移動電話銷售服務指定名稱。

    在每個服務內(nèi)可以有幾個方法、或者 operation ,WSDL 通過 <operation> 元素來引用它們。樣本應用程序有兩個要表示的方法: getListOfModels 和 getPrice 。因此,您需要提供兩個 <operation> 元素,每個元素有一個 name 。 我已經(jīng)使用 <operation> 元素的 name 屬性命名了每個操作。

    此時,WSDL 文件看上去象 清單 1。


    清單 1:定義操作

     1<?xml version="1.0" encoding="UTF-8" ?> 
     2<definitions  name="MobilePhoneService" 
     3     targetNamespace="www.mobilephoneservice.com/MobilePhoneService-interface" 
     4     xmlns="http://schemas.xmlsoap.org/wsdl/" 
     5     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
     6     xmlns:tns="http://www.mobilephoneservice.com/MobilePhoneService" 
     7     xmlns:xsd="http://www.w3.org/1999/XMLSchema"> 
     8     <portType name="MobilePhoneService_port"> 
     9             <operation name="getListOfModels "> 
    10                     
    11                     
    12             </operation> 
    13             <operation name="getPrice"> 
    14                     
    15                         
    16             </operation> 
    17     </portType> 
    18</definitions> 
    19


    步驟 2:指定參數(shù)
    Listing 2: Defining parameters 
            
           
     1<?xml version="1.0" encoding="UTF-8" ?> 
     2<definitions  name="MobilePhoneService" 
     3targetNamespace="http://www.mobilephoneservice.com/MobilePhoneService-interface" 
     4xmlns="http://schemas.xmlsoap.org/wsdl/" 
     5xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
     6xmlns:tns="http://www.mobilephoneservice.com/MobilePhoneService" 
     7xmlns:xsd="http://www.w3.org/1999/XMLSchema"> 
     8<types> 
     9<xsd:schema targetNamespace="http://www.mobilephoneservice.com/MobilePhoneService" 
    10xmlns="http://www.w3.org/1999/XMLSchema/"> 
    11<xsd:complexType name="Vector"> 
    12<xsd:element name="elementData" type="xsd:String" /> 
    13<xsd:element name="elementCount" type="xsd:int" /> 
    14</xsd:complexType> 
    15</xsd:schema> 
    16</types> 
    17<message name="ListOfPhoneModels"> 
    18<part name="models" type="tns:Vector"> 
    19</message> 
    20<message name="PhoneModel"> 
    21<part name="model" type="xsd:String"> 
    22</message> 
    23<message name="PhoneModelPrice"> 
    24<part name="price" type="xsd:String"> 
    25</message> 
    26<portType name="MobilePhoneService_port"> 
    27<operation name="getListOfModels "> 
    28<output message="ListOfPhoneModels"/> 
    29</operation> 
    30<operation name="getPrice"> 
    31<Input message="PhoneModel"/> 
    32<output message="PhoneModelPrice"/> 
    33</operation> 
    34</portType> 
    35</definitions> 
    36      


    定義好操作(或方法)以后,現(xiàn)在需要指定將向它們發(fā)送和從它們返回的參數(shù)。在 WSDL 術(shù)語中,所有參數(shù)稱為“消息”。認為您是在遞送消息而結(jié)果得到返回的消息是有用的。方法調(diào)用是這樣一種操作:它準備返回“消息”來響應進入的消息。

    請回憶,在第一步驟中有兩個操作要表示。第一個操作 getListOfModels 不必獲得任何參數(shù)并且返回一個字符串數(shù)組,其中每個字符串表示移動電話的型號。因此,必須定義一個包含字符串數(shù)組的 <message> 元素。

    看看 清單 2 中的各種 <message> 元素。其中的第一個元素有一個等于 ListOfPhoneModels 的名稱屬性(該消息的邏輯名稱),以及名稱為 models 的單個 <part> 元素,這意味著該 ListOfPhoneModels 是一個“只含有一個 part 的”消息,其中僅有的這個 part 的名稱是“models”。消息可以有任意多個 part ― 只要為它們起不同的名稱,以唯一標識。

    我已包括了 <part> 元素的另一個屬性,它就是 type 。將這個“type”屬性當作 C++ 或 Java 中的數(shù)據(jù)類型。我已經(jīng)將 models 的數(shù)據(jù)類型指定為 tns:Vector。(請回憶,我在 <definitions> 根元素中指定了一些名稱空間,其中之一是 tns 。)這個類型即指 MobilePhoneService 名稱空間。這意味著當編寫 WSDL 時,您可以創(chuàng)建自己的名稱空間。現(xiàn)在您也許會問兩個邏輯問題:為什么?和怎么做?

    要回答 為什么,讓我們以 getListOfModels 操作返回的字符串數(shù)組為例。WSDL 使用 XML 模式定義(XSD)定義的一些原始數(shù)據(jù)類型(諸如 int、float、long、short、byte、string、Boolean 等等),并允許您直接使用它們,或者以這些原始數(shù)據(jù)類型構(gòu)建復雜數(shù)據(jù)類型后,在消息中使用它們。這就是為什么當引用復雜數(shù)據(jù)類型時,您需要定義自己的名稱空間。在本例中,需要為 array of strings 構(gòu)建一個復雜數(shù)據(jù)類型。

    現(xiàn)在來看 怎么做問題,您將使用 XSD 創(chuàng)建自己的名稱空間。為實現(xiàn)這個目的,我在 <types> 元素中使用了 xsd:complexType 元素用來定義稱為 Vector 的數(shù)據(jù)類型。 Vector 使用兩個原始數(shù)據(jù)類型:string(元素數(shù)據(jù))和 Integer(元素計數(shù))。因此, Vector 成為名稱空間的一部分并可以通過別名 tns 來引用。

    在 清單 2 中,我以類似的方式定義了另外兩個消息 PhoneModel 和 PhoneModelPrice 。這兩個消息只使用了 xsd 名稱空間中的原始數(shù)據(jù)類型 string,因此您不必為使用它們而定義任何更復雜的數(shù)據(jù)類型。

    您也許已經(jīng)注意到當創(chuàng)建 <message> 元素時,沒有指定這些消息是進入?yún)?shù)還是返回值。這是一個您將在 <portType> 元素內(nèi)的 <operation> 元素中完成的工作。因此,正如您在 清單 2 中所看到的,我已經(jīng)將 <input> 和 <output> 元素都添加到這兩個操作中。每個 input 元素通過消息名來引用它并將它當作用戶調(diào)用該操作時要提供的參數(shù)。類似地,每個 <output> 元素引用一個消息;它將該消息當作操作調(diào)用的返回值。

    至今, 清單 2準確地限定了目前的討論的范圍。

    步驟 3:消息傳遞和傳輸

    我以一種抽象方式定義了操作和消息,而不考慮實現(xiàn)的細節(jié)。實際上,WSDL 的任務是定義或描述 Web 服務,然后提供一個對外部框架的引用來定義 WSDL 用戶將如何實現(xiàn)這些服務。可以將這個框架當作 WSDL 抽象定義和它們的實現(xiàn)之間的“綁定( binding )”。

    當前,最流行的綁定( binding )技術(shù)是使用簡單對象訪問協(xié)議(SOAP)。WSDL 將指定能夠訪問 Web 服務實際實現(xiàn)的 SOAP 服務器,并且從那時起 SOAP 的整個任務就是將用戶從 WSDL 文件帶到它的實現(xiàn)。SOAP 是本系列文章中下一部分的主題,所以我將暫時避免討論 SOAP 細節(jié)而繼續(xù)集中講述 WSDL 編寫。

    WSDL 編寫的第三個步驟是描述將 SOAP 與 WSDL 文件綁定到一起的過程。您將把 <binding> 元素包括到 <definitions> 元素內(nèi)。這個 binding 元素應該有 name 和 type 屬性。 name 將標識這個綁定而 type 將標識您希望與這個綁定相關(guān)聯(lián)的 portType(一組操作)。在 清單 3 中,您會發(fā)現(xiàn) <portType> 元素的 name 與 <binding> 元素的 type 屬性值相匹配。

    WSDL binding 元素包含您將用于綁定用途的外部技術(shù)的聲明。因為正在使用 SOAP,所以這里將使用 SOAP 的名稱空間。WSDL 術(shù)語中,對外部名稱空間的使用稱為 extensibility 元素。

    在 清單 3 中,您將看見一個空的 <soap:binding/> 元素。該元素的用途是聲明將把 SOAP 作為綁定和傳輸服務使用。

    <soap:binding> 元素有兩個屬性:style 和 transport。style 是一個可選屬性,它描述該綁定內(nèi)操作的性質(zhì)。transport 屬性指定 HTTP 作為該綁定將使用的級別較低的傳輸服務。

    SOAP 客戶機將從 WSDL 文件中讀取 SOAP 結(jié)構(gòu)并與另一端的 SOAP 服務器協(xié)調(diào),所以必須特別關(guān)注 interoperability 。我打算在本系列文章的第三部分詳細講述該問題。

    在空的 <soap:binding/> 元素后面,有兩個 WSDL <operation> 元素,分別表示步驟 1 的操作。每個 <operation> 元素提供各自操作的綁定細節(jié)。因此,我提供了另一個 extensibility 元素,即 <soap:operation/> (仍然是一個空元素,與它發(fā)生的那個操作相關(guān))。該 <soap:operation/> 元素有一個 soapAction 屬性,SOAP 客戶機將使用該屬性創(chuàng)建 SOAP 請求。

    請回憶步驟 2 中, getListOfModels 操作只有輸出而無任何輸入。因此,必須為該操作提供一個 <output> 元素。該輸出包含 <soap:body/> 元素(仍然是一個空元素,與它發(fā)生的那個操作相關(guān))。SOAP 客戶機需要該信息來創(chuàng)建 SOAP 請求。 <soap:body/> 的名稱空間屬性值應該與您將部署到 SOAP 服務器上的 service 的名稱相對應,SOAP 服務器將在在本系列文章的下一部分中講述。

    您已幾乎要完成步驟 3 了。只要將下一個操作復制到這個操作的后面,您將完成 清單 3。

    步驟 4:概括

    您已經(jīng)生成了一個完整描述服務 interface 的 WSDL 文件。現(xiàn)在,WSDL 需要一個附加步驟來創(chuàng)建該 WSDL 文件的概要。WSDL 將該文件稱為 implementation 文件,在本系列文章的第四部分中,當您在 UDDI 注冊中心發(fā)布 Web 服務時,會使用它。請看 清單 4― 這個 WSDL 實現(xiàn)文件。它的主要特性如下:

    除了
    清單 4(實現(xiàn)文件)引用不同的 targetNamespace 去引用實現(xiàn)文件以外, <definitions> 根元素和 清單 3(WSDL 接口文件)中的完全相同。
    有一個
    <import> 元素,該元素引用 清單 3的接口文件(文件名 MobilePhoneService-interface.wsdl)和它的名稱空間。
    有一個
    <service> 標記,其中有一個表示該服務的邏輯名 name 。在 service 元素內(nèi)有一個引用在 清單 3中創(chuàng)建的 SOAP 綁定的 port 元素。

    將 IBM 的 Web Services ToolKit(WSTK)用于 WSDL 編寫

    現(xiàn)在,Web 服務已經(jīng)完全就緒用于部署。我已經(jīng)展示了如何手工創(chuàng)建這些文件(使用象 emacs 這樣的簡單文本編輯器)。可以使用諸如 IBM 的 WSTK(請參閱 參考資料以獲得該工具箱以及本文提到的其它參考資料的鏈接)之類的 Web 服務編寫工具來生成相同的這些文件。

    WSTK 可以使用向?qū)椭^程來生成這些文件。用戶可以生成與我在以上教程中演示的同樣兩種方法的 WSDL 文件,并將 WSTK 文件和 清單 3和 4中的 WSDL 文件作比較。

    您將注意到下列差異:

    WSTK
    依照邏輯規(guī)則創(chuàng)建了所有名稱屬性;在本示例中,我使用了自己視為方便的名稱。
    WSTK 為每個操作至少生成一個 input
    標記,即使該操作不必獲得任何輸入。 listAllPhoneModels 操作沒有任何 input 元素,但是如果使用 WSTK 生成相同文件,它將因為包含這個方法的一個空 input 元素。
    WSTK 產(chǎn)生了除已生成的兩個文件以外的第三個文件。這第三個文件是
    SOAP 引擎用于服務部署的 SOAP 部署描述符。我將在本系列文章中討論服務部署。
    在這部分中,我演示了手工進行 WSDL 編寫以創(chuàng)建接口和實現(xiàn)文件,并與 IBM 的 Web Services ToolKit 生成的文件作了比較。在本系列的下一部分中,我將討論在 SOAP 服務器上部署這個 WSDL 服務。
    posted @ 2009-02-19 09:50 zhuyongjp 閱讀(437) | 評論 (0)編輯 收藏
    僅列出標題
    共3頁: 上一頁 1 2 3 
     
    主站蜘蛛池模板: 在线观看免费黄色网址| 久久久婷婷五月亚洲97号色| 国产乱弄免费视频| 四虎免费大片aⅴ入口| 免费成人福利视频| 免费A级毛片无码A∨免费| 久久久久久毛片免费播放| 国产成人无码区免费内射一片色欲| 亚美影视免费在线观看| 72pao国产成视频永久免费| 精品免费久久久久国产一区| caoporn国产精品免费| 久久www免费人成看国产片| XXX2高清在线观看免费视频| 成在线人视频免费视频| a色毛片免费视频| 中国极品美軳免费观看| 久别的草原电视剧免费观看| 久久久久久一品道精品免费看| 91av免费观看| 一色屋成人免费精品网站| 无码国产精品一区二区免费虚拟VR| 免费人成在线视频| 国产免费av一区二区三区| 免费乱码中文字幕网站| 国产专区一va亚洲v天堂| 亚洲成AV人片在线观看无码| 亚洲视频在线免费看| 亚洲欧洲日韩极速播放| 男女猛烈xx00免费视频试看| 特级毛片aaaa免费观看| 免费看成人AA片无码视频吃奶| 久久久久久成人毛片免费看| 麻豆一区二区免费播放网站| 国产精品免费看久久久无码| 亚洲日韩在线中文字幕第一页| 亚洲av丰满熟妇在线播放| 国产亚洲精品bv在线观看 | 国产美女在线精品免费观看| 免费在线观看理论片| 亚洲伊人久久精品影院|