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

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

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

    精彩的人生

    好好工作,好好生活

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

    #

    http://www.yesky.com/SoftChannel/72342371961929728/20030821/1723269.shtml

    概述

      本文介紹了一個比較簡單實用的基于Java的SOAP引擎——Apache組織推出的Axis——的
    安裝、配置和應用開發(fā)方法,希望對有興趣做基于Java的Web Services應用開發(fā)的朋友有所
    幫助。

      Axis簡介

      Axis是Apache組織推出的SOAP引擎,Axis項目是Apache組織著名的SOAP項目的后繼項目
    ,目前最新版本是采用Java開發(fā)的1.1版本,C++的版本正在開發(fā)之中。Axis v1.1軟件包可
    以從http://ws.apache.org/axis/dist/1_1/下載得到。

      Axis的安裝



      應用Axis開發(fā)Web Services,你需要有一個支持Servlet的服務器引擎,比如廣為人知

    的Tomcat(Tomcat也是由Apache組織所提供的,目前的最新版本為4.1.24,下載地址為http

    ://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.24/)。在此之前當然

    你機器必須已經裝好了JDK1.3以上的版本,當安裝好Tomcat之后,只需將下載的Axis軟件包
    解壓縮,將其中的“webapps”目錄下的“axis”目錄整個拷貝到Tomcat安裝目錄下的“web
    apps”目錄下即可。

      Axis的配置

      Axis基于Java開發(fā),可以部署于多種操作系統(tǒng),使用前需要配置一系列的系統(tǒng)變量,在
    此假定你已經在本機上裝好了Tomcat 4.0以上的版本,需要配置的系統(tǒng)變量如下表所示:

    CATALINA_HOME
    C:\Tomcat_4_1

    (此處應為Tomcat的安裝位置,注意路徑名中不要有空格)

    AXIS_HOME
    %CATALINA_HOME%\webapps\axis

    AXIS_LIB
    %AXIS_HOME%\lib

    AXISCLASSPATH
    %AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging

    .jar;%AXIS_LIB%\jaxrpc.jar; %AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar; %AXI
    S_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar


      如果你不愿做這么繁瑣的類路徑設置,可以直接將axis軟件包中“l(fā)ib”目錄下的所有.
    jar文件加入到系統(tǒng)環(huán)境變量CLASSPATH中即可。

      Axis的測試

      安裝配置完畢后,應測試一下是否Axis可以正確運行了。

      啟動Tomcat服務器,在瀏覽器中訪問http://localhost:8080/axis/happyaxis.jsp,如
    果頁面顯示有錯誤,則需要回頭檢查一下相關配置是否正確,如果瀏覽頁面能正確顯示出系
    統(tǒng)組件、屬性等參數(shù)配置信息,則表示安裝成功,如下圖所示:

      服務的發(fā)布

      Axis提供了兩種服務發(fā)布方式,一種是即時發(fā)布(Instant Deployment),一種是定制
    發(fā)布(Custom Deployment)。

      使用即時發(fā)布

      對即時發(fā)布的支持是Axis的特色之一,使用即時發(fā)布使用戶只需有提供服務的Java類的
    源代碼,即可將其迅速發(fā)布成Web服務。每當用戶調用這類服務的時候,Axis會自動進行編
    譯,即使服務器重啟了也不必對其做任何處理,使用非常簡單快捷。

      使用即時發(fā)布首先需要一個實現(xiàn)服務功能的Java源文件,將其擴展名改為.jws(Java W
    eb Service的縮寫),然后將該文件放到“……\webapps\axis”目錄下即可。

      在此給出一個從英里到公里的長度單位轉換的服務,其源碼如下:

    文件Distance.jws

    /**

    * @author 飛鷹

    */

    public class Distance

    {

    public double convertMile2Kilometre( double mile )

    {

    //實現(xiàn)英里到公里的距離轉換

    return mile * 1.609;

    }//convertMile2Kilometre()

    }/* Distance */


      將其放到“……\webapps\axis”目錄,通過訪問http://localhost:8080/axis/Distan
    ce.jws?wsdl可以看到這個服務的WSDL描述文件,這說明Distance服務被成功發(fā)布了。如下
    圖所示:
    使用定制發(fā)布

      即時發(fā)布是一項令人激動的技術,它使Web服務的開發(fā)變得如此簡單;然而即時發(fā)布并
    不總是最好的選擇,比如有些應用系統(tǒng)是第三方提供的,我們沒有購買源代碼,只有.clas
    s文件,但我們又希望將這個應用系統(tǒng)的一些功能對外發(fā)布成Web服務,使其能夠在更大范圍
    內產生作用,這個時候即時發(fā)布技術就無能為力了。此外,即時發(fā)布技術并不靈活,無法進
    行更多的服務配置,這使得它并不能滿足一些特定系統(tǒng)的需求。

      因此,Axis提供了另一種服務發(fā)布方式,這就是定制發(fā)布。

      在此給出一個從加侖到升的容積單位轉換的服務,其源碼如下:

      文件Capacity.java

    package samples.capacity;


    /**

    * @author 飛鷹

    */

    public class Capacity

    {

    public double convertGallon2Litre( double gallon )

    {

    //實現(xiàn)加侖到升的容積轉換


    return gallon * 4.546;

    }//convertGallon2Litre()

    }/* Capacity */


      將其編譯成.class文件,放置到“……\webapps\axis\samples\capacity”目錄下,即
    可著手進行發(fā)布。

      定制發(fā)布不需要構建.jws文件,但必須創(chuàng)建服務發(fā)布描述文件deploy.wsdd(Web Servi
    ce Deployment Descriptor的縮寫),這個文件負責描述服務的名稱、入口等信息,其內容
    如下:

      文件deploy.wsdd

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

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


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

    <parameter name="className" value="samples.capacity.Capacity"/>

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

    </service>


    </deployment>


      將該文件也放到“……\webapps\axis\samples\capacity”目錄下,然后可以采用Axi
    s提供的一個客戶端管理工具——AdminClient來完成服務的定制發(fā)布。

      在“……\webapps\axis\samples\capacity”目錄下,運行:

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


      可以看到以下運行結果:

    Processing file deploy.wsdd

    <Admin>Doneprocessing</Admin>


      這表明Capacity服務定制發(fā)布完成。

      通過訪問http://localhost:8080/axis/services/Capacity?wsdl可以看到這個服務的W
    SDL描述文件,這說明Capacity服務被成功發(fā)布了。如下圖所示:


    服務的訪問

      GET方式的服務訪問

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

    文件HelloWorld.jws

    /**

    * @author 飛鷹

    */

    public class HelloWorld

    {

    public String helloWorld()

    {

    //在服務器端打印輸出

    System.out.println( "Hello World!" );


    //返回相應字符串

    return "Hello World!";

    }//helloWorld()


    }/* HelloWorld */


      這個服務給出一個名位“helloWorld”的無入口參數(shù)的操作,返回一個內容為“Hello
    World!的字符串”,同時在服務器端打印“Hello World!”,將該文件放到“……\webap
    ps\axis”目錄下,即可通過GET方法直接訪問該服務,訪問的地址為http://localhost:808
    0/axis/HelloWorld.jws?method=helloWorld,可以看到返回的SOAP信封消息,同時服務器
    端給出了相應的顯示信息“Hello World!”這表明HelloWorld服務被成功訪問了。如下圖
    所示:



      客戶端服務訪問編程

      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對象,在訪問服務之前,首先要對Call對象設置相應的參數(shù),包括服務的位置、操
    作名、入口參數(shù)、返回值類型等,最后調用Call對象的invoke方法訪問服務。

      以下給出了一個客戶端訪問Web服務的例程——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;


    /**

    * @author 飛鷹

    */

    public class AXISTest

    {

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

    {

    Service service = new Service();

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



    //////////訪問即時發(fā)布的Distance服務

    //設置訪問點

    call.setTargetEndpointAddress( "http://localhost:8080/axis/Distance.jws" );


    //設置操作名

    call.setOperationName( "convertMile2Kilometre" );


    //設置入口參數(shù)

    call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );

    call.setReturnType( XMLType.XSD_DOUBLE );

    Double d1 = new Double( 190 );


    //調用服務

    System.out.println( d1 + " 英里相當于 " +

    call.invoke( new Object[] {d1} ) + " 公里!" );




    //////////訪問定制發(fā)布的Capacity服務

    call = ( Call ) service.createCall();

    //設置訪問點

    call.setTargetEndpointAddress( "http://localhost:8080/axis/services/Capacity" );


    //設置操作名

    call.setOperationName( "convertGallon2Litre" );


    //設置入口參數(shù)

    call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );

    call.setReturnType( XMLType.XSD_DOUBLE );

    d1 = new Double( 10.00 );


    //調用服務

    System.out.println( d1 + " 加侖相當于 " +

    call.invoke( new Object[] {d1} ) + " 升!" );

    } //main()

    }/* AXISTest */


      編譯運行后運行可以看到以下的結果:

      190.0英里相當于305.71公里!

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

      總結

      Web Services是未來網(wǎng)絡應用的發(fā)展方向,SOAP和WSDL是Web Services的核心協(xié)議,Ax
    is給出了一個很好的SOAP實現(xiàn),它使得開發(fā)Web Services應用變得輕松而有趣。
    posted @ 2006-03-09 11:24 hopeshared 閱讀(871) | 評論 (0)編輯 收藏

    CSDN - 專家門診 - Java J2SE / 基礎類問題

    回復人: panq(漫隨天外) ( ) 信譽:100 2001-10-25 13:40:12Z 得分:300

    簡單對象訪問協(xié)議(SOAP):
    用于Internet上的分布式計算,可以實現(xiàn)跨平臺跨編程語言的對象訪問和方法調用.
    它通過HTTP協(xié)議實現(xiàn)參數(shù)的傳輸,同時以特定的XML格式表示參數(shù).這樣,只需要一個支持H
    TTP協(xié)議的WEB服務器和一個XML解析器就可以實現(xiàn)簡單的SOAP功能.由于成為了標準,所以
    會有越來越多的軟件支持它.大家若有興趣的話可以去看SOAP1.1標準.
    同時,還有許多SOAP的開發(fā)工具,以簡化SOAP的開發(fā).隨著這些開發(fā)工具的完善,我們
    甚至可以不用管具體的SOAP格式就可以開發(fā)SOAP應用.
    下面以APACHE的SOAP包為例,舉個例子:
    服務器端的Class:
    package samples.soap;
    public class SOAPCal {
    double rate;
    public SOAPCal() {
    rate = 8.7;
    }
    public void setRate(double rate) {
    this.rate = rate;
    }
    public Double calculate(int direction, double value) {
    Double retVal;
    switch(direction) {
    case 0:
    retVal = new Double(value * rate);
    break;
    case 1:
    retVal = new Double(value / rate);
    break;
    default:
    retVal = null;
    }
    return retVal;
    }
    }
    客戶端Class:
    package samples.soap;
    import java.io.*;
    import java.util.*;
    import java.net.*;
    import org.w3c.dom.*;
    import org.apache.soap.util.xml.*;
    import org.apache.soap.*;
    import org.apache.soap.encoding.*;
    import org.apache.soap.encoding.soapenc.*;
    import org.apache.soap.rpc.*;
    public class SOAPCalUser {
    public static void main(String[] args) throws Exception {
    if (args.length != 3
    && (args.length != 4 || !args[0].startsWith("-"))) {
    System.err.println("Usage:");
    System.err.println(" java " + SOAPCalUser.class.getName() +
    " [-encodingStyleURI] SOAP-router-URL name " +
    "(0: dollor to yuan | 1: yuan to dollor) value");
    System.exit (1);
    }
    int offset = 4 - args.length;
    String encodingStyleURI = args.length == 11
    ? args[0].substring(1)
    : Constants.NS_URI_SOAP_ENC;
    URL url = new URL(args[1 - offset]);
    int direction = Integer.parseInt(args[2 - offset]);
    double value = Double.parseDouble(args[3 - offset]);
    Call call = new Call();
    call.setTargetObjectURI("urn:SOAPCal");
    call.setMethodName("calculate");
    call.setEncodingStyleURI(encodingStyleURI);

    Vector params = new Vector();
    params.add(new Parameter("direction", int.class, new
    Integer(direction), null));
    params.add(new Parameter("value", double.class, new Double(value),
    null));
    call.setParams(params);
    Response resp;
    try {
    resp = call.invoke(url, "");
    } catch (SOAPException e) {
    System.err.println("Caught SOAPException (" +
    e.getFaultCode() + "): " +
    e.getMessage());
    return;
    }
    // Check the response.
    if (!resp.generatedFault()) {
    Parameter ret = resp.getReturnValue();
    Object retVal = ret.getValue();
    System.out.println(retVal != null ? "\n" + retVal : "I don't
    know.");
    } else {
    Fault fault = resp.getFault();
    System.err.println("Generated fault: ");
    System.out.println (" Fault Code = " +
    fault.getFaultCode());
    System.out.println (" Fault String = " +
    fault.getFaultString());
    }
    }
    }

    package samples.soap;
    import java.io.*;
    import java.util.*;
    import java.net.*;
    import org.w3c.dom.*;
    import org.apache.soap.util.xml.*;
    import org.apache.soap.*;
    import org.apache.soap.encoding.*;
    import org.apache.soap.encoding.soapenc.*;
    import org.apache.soap.rpc.*;

    public class SOAPCalAdmin {
    public static void main(String[] args) throws Exception {
    if (args.length != 2
    && (args.length != 3 || !args[0].startsWith("-"))) {
    System.err.println("Usage:");
    System.err.println(" java " + SOAPCalAdmin.class.getName()
    + " [-encodingStyleURI] SOAP-router-URL name " +
    "rate ");
    System.exit (1);
    }
    int offset = 3 - args.length;
    String encodingStyleURI = args.length == 11
    ? args[0].substring(1)
    : Constants.NS_URI_SOAP_ENC;
    URL url = new URL(args[1 - offset]);
    double rate = Double.parseDouble(args[2 - offset]);
    Call call = new Call();
    call.setTargetObjectURI("urn:SOAPCal");
    call.setMethodName("setRate");
    call.setEncodingStyleURI(encodingStyleURI);
    Vector params = new Vector();
    params.add(new Parameter("rate", double.class, new Double(rate),
    null));
    call.setParams(params);
    Response resp;
    try {
    resp = call.invoke(url, "");
    } catch (SOAPException e) {
    System.err.println("Caught SOAPException (" +
    e.getFaultCode() + "): " +
    e.getMessage());
    return;
    }
    // Check the response.
    if (!resp.generatedFault()) {
    System.out.println("The rate has been changed.");
    } else {
    Fault fault = resp.getFault();
    System.err.println("Generated fault: ");
    System.out.println (" Fault Code = " +
    fault.getFaultCode());
    System.out.println (" Fault String = " +
    fault.getFaultString());
    }
    }
    }
    發(fā)布用的XML文件dd.xml:
    <isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
    id="urn:SOAPCal">
    <isd:provider type="java"
    scope="Application"
    methods="setRate calculate">
    <isd:java class="samples.soap.SOAPCal"/>
    </isd:provider>
    </isd:service>
    這個程序的功能是設置和計算美元/人民幣的兌換價格,用
    java org.apache.soap.server.ServiceManagerClient
    http://sb3server:8080/soap/servlet/rpcrouter deploy dd.xml
    把服務器端程序發(fā)布到TOMCAT上,然后在客戶端用:
    java samples.soap.SOAPCalAdmin http://sb3server:8080/soap/servlet/rpcrouter
    XX.XX
    來設置匯率(1美元兌換多少人民幣), 用
    java samples.soap.SOAPCalUser http://sb3server:8080/soap/servlet/rpcrouter
    (1|0) XX.XX
    來換算,其中1和0代表從人民幣到美元和從美元到人民幣,下一個參數(shù)是要換算的錢數(shù).
    另外,在http://www.xmethods.com/gettingstarted/apache.html
    有一個簡單的教程介紹怎樣用APACHE的SOAP包寫SOAP客戶端程序.講解比較詳細.
    注意點:
    *如果SOAP傳回來的參數(shù)是一個CLASS,這個CALSS會被序列化(Serializer)為一段XML
    代碼,在客戶端接這個CLASS時,仍然需要一個同名CLASS,而且那些被傳遞過來的數(shù)據(jù)的SE
    T和GET方法名和參數(shù)名要相同.如果是自定義的CLASS,就要做maping聲明.聲明方法見APA
    CHE SOAP包的samples\addressbook\DeploymentDescriptor.xml文件中isd:mappings的
    寫法.
    在客戶端調用時要加上
    SOAPMappingRegistry smr = new SOAPMappingRegistry();
    BeanSerializer beanSer = new BeanSerializer();
    smr.mapTypes(/*encodingStyle*/Constants.NS_URI_SOAP_ENC,
    new QName(/*Namespace URI*/"urn:xml-soap-address-demo", /*Local
    Part*/"address"),
    /*Class type*/Address.class, /*java2XMLClassName*/beanSer,
    /*xml2JavaClassName*/beanSer);
    call.setSOAPMappingRegistry(smr);
    *目前不是所有的CLASS都能被序列化,如Hashtable就不行,所以最好用簡單的數(shù)據(jù)類
    型,如String,String,Integer,Double及其數(shù)組來傳遞變量,對復雜的參數(shù),可以直接做成
    XML Document傳遞(使用Constants.NS_URI_LITERAL_XML作為EncodingStyleURI),這樣就
    省得客戶端專門做個CLASS來接參數(shù),也方便跨語言的調用.在使用APACHE的SOAP包時,XML
    Document在客戶端會被轉換為XML DOM的Element class.
    現(xiàn)在唯一的方法是自己寫進行序列化的程序,不過以后也許會有標準的序列化方法.

    *CLASS被序列化時CLASS中的靜態(tài)的變量是不會被加入的來的,這一點要注意.

    posted @ 2006-03-09 11:23 hopeshared 閱讀(3916) | 評論 (1)編輯 收藏

    作者: ZDNet China

    現(xiàn)在是鉆研專業(yè)術語的時候了。我們將談談在P2P網(wǎng)
    絡體系中XML以及其他Web服務的使用情況,并從技術的角度指出嘗試將各種“新”技術嫁接
    在一起的好處。



    從巴赫開始


    巴赫——偉大的作曲家——以他的“為了藝術而藝術”而聞名于世。換句話說,他創(chuàng)作音樂
    并并不需要特殊的原因或者動機,僅僅是因為他覺得自己需要這么做。

    有時候,技術領域也遵循著同樣的道路——我們創(chuàng)造并使用新技術僅僅是因為我們覺得我們


    需要這么做。當然,在巴赫的年代,不會每年有五千萬份廣告來告訴他“你需要創(chuàng)作大提琴

    協(xié)奏曲來緊跟時代”。


    把多種技術集合在一起實際上會創(chuàng)造新的技術。例如,電技術加上麥克風和揚聲器就導致了
    一系列新技術的出現(xiàn),如電話和收音機;再加上視頻技術又出現(xiàn)了更復雜的技術,如電視和
    可視電話。那么根據(jù)這一原則,Web技術加上P2P會產生更復雜的東東,這些東東或許會派上
    用場,那么它們究竟是些什么呢?



    Web服務已經P2P了么?

    或許Web服務本身就是P2P的。實際上,已經有幾篇文章在探討Web服務與P2P的“收斂(conv
    ergence)”。這里的“收斂”指的是Web服務與P2P共同使用。

    或許看到這里你會問:“如何在Web服務中利用P2P技術?”呵呵,這個問題的提法本身就不
    對。你應該這么問自己:“我如何在我的P2P網(wǎng)絡中利用Web服務呢?”



    P2P網(wǎng)絡

    開發(fā)者常常把P2P技術稱為P2P網(wǎng)絡。這是因為“peer”實際上就是網(wǎng)絡中的“節(jié)點”。由于

    P2P是一個高層次的技術,實際的底層網(wǎng)絡對這個概念并不重要。盡管實際上,網(wǎng)絡常常是T
    CP/IP網(wǎng)絡,并利用Internet來從一個peer到達另一個peer,如同IP地址中的節(jié)點那樣。


    P2P網(wǎng)絡的應用程序導致了若干種類型的應用程序。從即時消息到文件共享以及分布式計算
    的每一樣事物都用到了P2P概念和技術。和P2P應用程序一樣,它們會遇到各種問題,而Web
    服務技術可以解決這些問題。



    Web服務對P2P的貢獻

    P2P的一個主要問題就是定位P2P服務以及理解底層通信協(xié)議。一般的P2P途徑在Internet上
    搜索適當?shù)腜2P應用程序并安裝定制應用程序。在更集成的環(huán)境下,常常用客戶API或者工具
    包提供了封裝,也就是隱藏了應用程序協(xié)議的細節(jié)。


    Web服務為定位應用程序提供了UDDI注冊服務。每一個注冊到UDDI數(shù)據(jù)庫的應用程序都包含
    語言(Web Services Description Language ,WSDL)的格式進行標準化的。

    WSDL描述指出了訪問服務的實際方法和參數(shù)。此外,它還提供了可以被服務器識別的傳輸和
    綁定協(xié)議。大多數(shù)Web服務通過XML和HTTP、用SOAP來綁定Web服務來傳輸SOAP消息。

    簡而言之,Web服務技術(無論故意使用還是無意的)可以解決設計、建立和配置P2P應用程

    序中的許多常見問題。聯(lián)合使用XML、SOAP、WSDL、HTTP和UDDI,使用Web服務的P2P應用程
    序將會更加標準、更易于訪問、更易于理解并更容易集成。

    posted @ 2006-03-09 11:20 hopeshared 閱讀(743) | 評論 (0)編輯 收藏

    作者: 高科華∣來源:Matrix

    J2EE 1.4簡介
    2003年11月24日,J2EE的JCP(Java Community Process)委員會投票一致通過了J2EE 1.4,這是過去兩年內發(fā)布的第一個主要版本。這個最新版的企業(yè)Java標準開放平臺增加了許多新的服務,J2EE 1.4 SDK支持這些服務,現(xiàn)在可以下載這個SDK了。這個SDK包括J2EE 1.4 應用服務器、J2SE 1.4.2和J2EE 1.4示例代碼。你可以下載整個SDK或單獨下載應用服務器或示例代碼。
    下面的技巧介紹了J2EE 1.4的一些新特點。也包括如何在Solaris、 Windows、 Linux、和 Mac OS X上安裝J2EE 1.4 SDK。但是沒有完全覆蓋這個平臺的所有新內容。關于J2EE 1.4新內容的更全面的介紹,請看J2EE v1.4 Application Server Release Notes。
    對Web Service的支持
    J2EE 1.4最重要、最受爭議的特點是對標準的Web Service的端對端的支持。有了J2EE 1.4,現(xiàn)在可以用HTTP之上的SOAP(Simple Object Access Protocol)使得J2EE組件(例如企業(yè)Bean和servlet)成為Web Service。
    J2EE 1.4要求應用服務器必須遵守WS-I Basic Profile 1.0,這個規(guī)范定義了Web service的傳輸和協(xié)議。這使得Web service是可以互操作的。
    與J2EE中Web service有關的關鍵技術如下:
    · Web Services for J2EE 1.1。結合單個J2EE技術創(chuàng)建Web service的主要是Web Services for J2EE。它定義了客戶端、service端以及容器之間的部署協(xié)議。新的部署描述符文件,webservices.xml,為每一種組件定義了部署模式。Web Services for J2EE 還定義了編程模型(JAX-RPC)、 使用JNDI查找提供service的對象、和安全。最后,它還提供了一個新的Handler對象,開發(fā)者可以用這種對象阻止和操作SOAP消息。
    · JAX-RPC 1.1 (Java API for XML-Remote Procedure Calls)。JAX-RPC是一個標準的遠程過程調用接口,它使用XML作為方法調用和返回值的序列化協(xié)議。JAX-RPC 把servlet和無狀態(tài)會話Beans定義為在SOAP和 WSDL (Web Services Description Language)的基礎上的XML Web service的service端。Service端是實現(xiàn)了Web service邏輯的軟件組件。JAX-RPC 的client接口定義了對Web service的遠程調用是如何發(fā)生的,以及參數(shù)和返回值(包括collection)是如何序列化的。JAX-RPC 1.1 還支持對安全Web services的基于SSL的驗證。
    · JAXR 1.0 (Java API for XML Registries)。 JAXR 把不同的XML注冊表統(tǒng)一到單個模型。程序員可以利用XML注冊表發(fā)現(xiàn)和查找service,訪問它們的內容和元數(shù)據(jù)。例如,你可以用應用創(chuàng)建工具訪問指定服務器上的注冊表,找出服務器提供了哪些service,設計SOAP客戶端使用其中的一個service。JARX還使得外部Web service客戶端可以訪問J2EE Web service。
    · SAAJ 1.2 (SOAP with Attachments API for Java)。SAAJ用具有MIME附件的SOAP消息處理客戶端和Web service之間的SOAP消息傳遞。MIME附件既可以用來發(fā)送文檔(對基于文檔的Web service而言)又可以用來發(fā)送傳遞大量數(shù)據(jù)的參數(shù)(對 RPC式的Web service)。 SAAJ還為帶附件的SOAP消息定義了DOM(Document Object model,文檔對象模型)。它允許用戶對如何編碼SOAP消息進行控制, 為重復或復雜的任務提供了automation hook。
    · JAXP 1.2 (Java API for XML Parsing)。這個包統(tǒng)一了解析和處理XML的各種方法。負責解析的類可以在部署時與運行時之間切換。JAXP 1.2包含了SAX 2.0、 DOM Level 2、和XSLT。
    Web層增強
    不是所有的J2EE 1.4中的Web層增強都與Web service有關。現(xiàn)有的核心技術也得到了更新。
    J2EE 1.4中的Web層最大的增強在于JSP 2.0。JSTL(JavaServer Pages Standard Tag Library)提供了范圍廣泛的通用tag,這些tag極大地方便了Web層的開發(fā)。JSTL還定義了新的表達式語言,這種語言可以用來編寫存儲在任何范圍內的Web層JavaBean組件的表達式。下一個技巧說明了如何使用幾種這樣的tag。
    JSP另一個主要的增強是方便地定義定制tag的能力。在JSP 2.0以前的版本中,定義定制tag要求編寫實現(xiàn)Tag接口的類。JSP 2.0仍然支持這種方法,但是它還允許用JSP代碼片斷定義定制tag(在JSP文件中定義),然后在多個地方使用所定義的定制tag。
    EJB 2.1
    J2EE 1.4的另一個重要特點是EJB 2.1,EJB 2.1提供了幾個新的增強。這些包括:
    l 無狀態(tài)會話Bean可以用作Web service端。
    l 新的Timer service可以設置成定時調用企業(yè)Bean的ejbTimeout()方法。可以用這個service定時調用商業(yè)邏輯。
    l EJB-QL增加了對結果集排序的ORDER BY子句和新的合計函數(shù)(AVG、MAX、MIN、SUM和COUNT)。
    l 現(xiàn)在消息驅動的Bean可以接受任何類型的消息,而不只是JMS消息(以前的版本只接受JMS消息)。現(xiàn)在連接器可以直接與MDB通訊,通過適配器把從外部系統(tǒng)傳來的消息翻譯成對MDB的調用。
    企業(yè)Java BluePrint for J2EE 1.4
    Java BluePrint示例應用是J2EE平臺的必要部分。示例應用展示了應用設計和開發(fā)的最佳實踐,提供了如何使用J2EE技術的例子。J2EE 1.4 SDK開發(fā)版本包含了AdventureBuilder,這是新增的J2EE的Web service示例應用。它也包含了原有的Java Pet Store和無線游戲示例應用。
    其他變化
    J2EE平臺其他的一些重要變化包括:
    l JACC 1.0(Java Authorization Contract for Containers ):允許自由選擇安全和基于角色的授權提供者。
    l Java Deployment API 1.1: 獨立于服務器的部署工具。
    l Java Message Service (1.1) 增強
    l J2EE Connectors 1.5:包括了對異步、雙向、多線程連接器的完全支持。
    l J2EE Deployment 1.1:包括了可代替DTD的用XML模式定義的部署描述符,為了向后兼容保留了DTD.
    l J2EE Management 1.0:用Java工具或非Java工具管理企業(yè)資源。
    l 新版JavaMail (1.3),Java Transaction API (JTA 版本1.01B), 和JDBC 3.0
    安裝服務器
    用J2EE 1.4新的GUI安裝程序安裝服務器很簡單。所支持的操作系統(tǒng)如下:
    l Solaris SPARC 8
    l Solaris SPARC 9
    l Windows 2000 Pro SP3+
    l Windows XP Pro SP1+
    l Windows 2000 Server SP3+
    l Windows Server 2003
    l Linux RedHat 8
    除了對Linux RedHat的支持以外,只需作很少的修改,甚至不需修改,服務器就能在許多其他的Linux版本環(huán)境運行。在Linux上安裝的主要要求是J2RE 1.4.1以上的版本。
    在所支持的任意一個操作系統(tǒng)上安裝服務器的步驟是:
    1. 下載適當?shù)能浖╤ttp://java.sun.com/j2ee/1.4/download-dr.html)。
    2. 運行下載的可執(zhí)行程序。
    在Macintosh OS X 或Darwin上安裝J2EE 1.4 SDK是可能的,盡管沒有宣稱對它們的支持。要在OS X 或Darwin上安裝J2EE 1.4 SDK,你必須有root訪問權限,J2RE必須是1.4.1以上的版本。
    在OS X 或Darwin上安裝J2EE 1.4 SDK的步驟如下:
    1. 下載SDK的Linux版本(http://java.sun.com/j2ee/1.4/download-dr.html)。下載的文件將是ELF二進制文件。
    2. 用unzip命令行實用程序將壓縮文件解壓到一個空目錄。必須用unzip,用象StuffIt這樣的程序是不行的。在提示符(‘$’)后輸入:
    $ unzip j2eesdk-1_4-dr-linux-eval
    3. 開始安裝,輸入:
    $ java -cp package/PackageFormat.jar:. appserv
    安裝程序會開始安裝SDK。如果偶爾不能看到安裝時顯示的提示,這時可以調整窗口的大小。
    4. 安裝程序要求輸入Java路徑時,輸入:
    /Library/Java/Home
    安裝程序會給出一個提示信息“server requires JDK 1.4.2. Java 2 version 1.4.1 will work properly”,選擇<continue>。
    5. 安裝程序完成后,還必須做些工作。第一件要做的工作是改變安裝目錄img/bin的訪問權限。輸入:
    $ chmod a+x /Users/yourname/SUNWappserver/imq/bin
    這里yourname是你的用戶名。(這假定服務器安裝在/Users/yourname。)
    6. 最后一步要求root訪問權限。服務器在/Library/Java/Home/jre/bin內查找java和javac,這個目錄還不存在。你必須創(chuàng)建這個目錄,創(chuàng)建這些程序的二進制代碼的符號連接。輸入:
    $ sudo mkdir -p /Library/Java/Home/jre/bin
    $ cd /Library/Java/Home/jre/bin
    $ sudo ln -s /Library/Java/Home/bin/java java
    $ sudo ln -s /Library/Java/Home/bin/javac javac
    sudo命令在第一次運行時會要求你輸入口令。如果你不是系統(tǒng)管理員,你必須以root身份登錄或su到root才能完成這些工作。
    7. 安裝到此已經完成。啟動應用服務器,輸入:
    $ cd /Users/yourname/SUNWappserver/bin
    $ asadmin start-domain

    JSTL(THE JAVA STANDARD TAG LIBRARY)
    過去幾年,我們一直自己編寫定制tag實現(xiàn)JSP頁面的顯示邏輯。已經建立了幾個流行的tag庫,用來執(zhí)行迭代、處理XML、調用輔助函數(shù)和訪問Web層JavaBean。這些庫的功能有許多重疊,更主要的是它們互不兼容。
    為了解決這個不兼容問題,JCP就一個共用邏輯和現(xiàn)實tag集達成了一致。這些tag通常在創(chuàng)建Web應用的視圖時非常有用。這個新的tag集被稱之為JSTL(JavaServer Pages Standard Tag Library)。
    JSTL不是J2EE 1.4必需的部分,因此,不要求應用服務器供應商對它的支持。然而,Sun的J2EE 1.4 SDK還是包含了JSTL,其他的供應商也很可能支持它。JSTL并不都是新的---J2EE 1.3容器早就有了JSTL 1.0。JSTL 1.1對JSTL進行了升級,以便利用JSP 2.0和J2EE 1.4的新特點。
    這個技巧說明了如何使用幾個新的JSTL tag。為了使用這些tag,必須了解新的JSP表達式語言(JSP Expression Language,JSP EL)。
    JSP表達式語言
    JSTL的基本思想是,JSP頁面格式化的大多數(shù)數(shù)據(jù)都是JSP Page狀態(tài)的。這些狀態(tài)包括:
    l page、request、session或application范圍的對象。
    l Request參數(shù)
    l JSP隱含對象(例如,pageContext)
    l HTTP header、cookie、和request 參數(shù)
    l Servlet上下文初始化參數(shù)
    關于JSP頁面可以使用的數(shù)據(jù)的完整列表,請看J2EE 1.4教程(http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPIntro7.html)。
    用戶定義的JavaBean(包括JavaBean和對企業(yè)Bean的引用)可以綁定到任何范圍的狀態(tài)變量。如果你在一個頁面上用代碼片斷創(chuàng)建了一個新的Bean,你只需使用<jsp:useBean>tag。否則,只能在EL表達式中用名稱訪問Bean。JSP 2.0表達式語言使用JavaBean的命名機制操縱所連接的Bean。這個語言也為JSP tag中所用的表達式定義了語法。JSP頁面編譯器把分隔符${和}之間的JSP語句看成表達式。
    解釋JSP表達式是如何工作的最容易的方法是用例子,下面我們就看一看這個技巧的示例代碼。
    示例代碼
    示例代碼是一個使用了兩個JavaBean的Web應用。JavaBean ColorScheme是一個映照,這個映照的鍵名是顏色名稱,鍵值是ColorBean對象。ColorBean有名稱(用這個名稱注冊到ColorScheme),red、green和blue顏色組件。ColorScheme繼承了javax.util.TreeMap。對ColorScheme迭代按名稱順序取得它的所有ColorBean對象。ColorBean繼承了java.awt.Color,因此,在JSP EL中可以使用它繼承的所有方法(包括JavaBean屬性)。
    應用的歡迎頁面,index.jsp,操作有幾百個ColorBean對象的ColorScheme對象。這些對象的數(shù)據(jù)來源于Web歸檔文件中的文本文件(rgb.txt)。文件中的數(shù)據(jù)有下面的格式:
    R G B Name
    240 248 255 AliceBlue
    index.jsp前面的一段代碼初始化ColorScheme Bean,以名稱“scheme”用session狀態(tài)存儲這個Bean,如下所示:
    <jsp:useBean id="scheme"
    class="com.elucify.tips.dec2003.ColorScheme"
    scope="session">

    <!-- Initialize this bean -->
    <%
    // Open a stream to the init file
    InputStream stream =
    application.getResourceAsStream("/rgb.txt");

    // Get a reference to the scheme bean
    ColorScheme colorScheme =
    (ColorScheme)pageContext.findAttribute(
    "scheme");

    // Load colors from stream
    try {
    colorScheme.load(stream);
    } catch (IOException iox) {
    throw new JspException(iox);
    }
    %>
    </jsp:useBean>

    (注意,如果使用tag文件代替代碼片斷,這個應用會更好。Tag文件是JSP 2.0的新特點,將在以后的使用技巧中介紹。)
    上面的代碼典型地使用了<jsp:useBean>tag初始化這個tag所創(chuàng)建的Bean。在index.jsp對scheme Bean初始化并把它放在session范圍內以后,其他JSP頁面就可以對這個scheme Bean的數(shù)據(jù)進行格式化。
    打印ColorScheme集大小的JSP代碼可能是下面這個樣子:
    <%
    ColorScheme scheme =
    (ColorScheme)session.getAttribute("scheme");
    out.println("The current color scheme has " +
    scheme.size() + " colors.");
    %>
    使用JSTL和JSP表達式語言,這個任務會更簡單,可讀性也更強。示例頁面Count.jsp就是這樣做的:
    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions"
    prefix="fn" %>

    The current color scheme has ${fn:length(scheme)} colors.

    第一行為JSTL函數(shù)包中的tag定義了前綴fn(關于這個包的更多信息,請看教程)。第二行是包含了表達式${fn:length(scheme)}的模板文本。JSP頁面在運行時用scheme對象的長度代換這個表達式。因為scheme是一個映照,其長度返回的是其中條目的個數(shù)。Length函數(shù)對所有Collection類型都是可用的。
    更有趣的示例是示例頁面ListColorNames.jsp,它列出了ColorScheme bean中的所有顏色的名稱:
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core"
    prefix="c" %>

    This is a list of the names of all of the colors
    in the current color scheme:

    <ol>
    <c:forEach var="entry" items="${scheme}">
    <li>${entry.key}</li>
    </c:forEach>
    </ol>
    行<%@taglib%>定義c為JSTL Core tag的前綴。這個頁面的其他部分定義了一個有序列表。使用<c:forEach>對scheme集中的所有條目迭代。所有Collection類都可用ForEach tag。接著把在var屬性中給出名稱的page變量賦給這個集中的每個值。
    當forEach tag的item屬性中的表達式的值是java.util.Map時,在var中命名的變量被設置為類型是java.util.Map.Entry的item。這時,迭代變量被稱為entry,因此,用表達式${entry.key}取得鍵名。
    在下面的例子中你會看到,可以用表達式${entry.value}得到每個entry的值。這是因為java.util.Map.Entry對象有getKey和getValue方法,表達式語言遵守JavaBean的命名約定。
    通常,JSP EL表達式${a.b.c.d}是用代碼a.getB().getC().getD()來計算的。這種表達式是對JavaBean屬性的相繼調用的簡化。
    示例頁面ShowColors.jsp顯示了scheme中包含的顏色,如下所示:

    This table demonstrates all of the colors
    in the current scheme.

    <TABLE BORDER="1" BGCOLOR="WHITE">
    <TR><TH>Name</TH><TH>Sample Text</TH><TH>Color Swatch</TH>
    <TH>Hex Code</TH><TH>Opposite Color</TH></TR>

    <!-- Loop over color entries in the scheme -->
    <c:forEach var="entry" items="${scheme}">

    <!-- Set two variables to improve -->
    <!-- readability of HTML below -->
    <c:set var="color"
    value="${entry.value.rgbHex}"/>
    <c:set var="name"
    value="${entry.key}"/>

    <TR>
    <TD>${name}</TD>
    <TD><FONT COLOR="${color}">${name}</FONT></TD>
    <TD BGCOLOR="${color}">${name}</FONT></TD>
    <TD>${color}</TD>
    <TD BGCOLOR="${entry.value.rgbComplement}">
    ${name}</TD>
    </TR>

    </c:forEach>

    如上所示,這個例子使用了<c:forEach>。兩個 <c:set> tag 把page屬性color和name分別設置到顏色和顏色名稱的hex表示。按照JavaBean命名約定,下面的行:
    <c:set var="color" value="${entry.value.rgbHex}"/>
    等效于Java代碼
    ColorBean cb = (ColorBean)entry.getValue();
    pageContext.setAttribute("color", cb.getRgbHex());
    模板文本中使用的color和name變量用來創(chuàng)建JSP頁面輸出中的table行。不用使用<c:get>tag,因為EL變量的值總是可以作為表達式引用,就象${color}這樣。
    最后一個示例頁面,ColorNameGrid.jsp,給出了JSTL tag更多的用法。它說明了如何使用JSTL tag進行下面的工作:
    l 訪問request參數(shù)
    l 用兩個不同的方法執(zhí)行有條件輸出
    l 使用EL比較和運算
    l 使用EL算術函數(shù)
    ColorNameGrid.jsp以多列的table打印ColorScheme中所有顏色的名稱。列數(shù)在1到10之間,根據(jù)request參數(shù)cols確定。如果列數(shù)超出了范圍就產生錯誤信息。
    ColorNameGrid.jsp的代碼如下:
    <!-- Initialize local variables -->
    <c:set var="cols" value="${param['cols']}"/>
    "c:set var="col" value="0"/>

    <!-- use the "choose" element to limit -->
    <!-- number of columns -->
    <c:choose>
    <c:when test="${cols > 0 && cols <= 10}">

    This is a grid of the names of all of the
    colors in the current color scheme:
    <p>

    <TABLE BORDER="0" BGCOLOR="#404040">
    <TR>
    <c:forEach var="entry" items="${scheme}">
    <c:set var="color" value="${entry.value}"/>

    <TD><FONT COLOR="${color.rgbHex}">${entry.key}
    </FONT></TD>

    <c:set var="col" value="${col+1}"/>

    <c:if test="${(col % cols) == 0}">
    </TR><TR>
    </c:if>

    </c:forEach>
    </TR>

    </TABLE>
    </c:when>

    <c:otherwise>
    <!-- Complain about unreasonable input -->

    ${cols} is an unreasonable number of columns.
    <p>
    Click <a href="index.jsp">here</a> to try again.
    </c:otherwise>

    </c:choose>
    第一個<c:set>tag取得request參數(shù)cols,把它賦給page屬性(屬性名也是cols),如下所示:
    <c:set var="cols" value="${param['cols']}"/>
    (這個頁面也可以不用page屬性cols,在需要的地方使用${param['cols']}。定義page屬性是為了使該頁面的可讀性更強。)
    第二個<c:set>tag用值1對page屬性col初始化。這個變量用來分隔列。
    <c:choose>tag很象Java中的if-else語句。<c:when>tag就象if and else if語句,<c:otherwise>tag就象最后的else語句。<c:choose>tag包含了一系列的<c:when>tag,每一個<c:when>tag都有一個包含表達式的test屬性。第一個<c:when>tag體的test表達式返回true,這個tag體執(zhí)行后包含在輸出中。如果沒有一個<c:when>的test表達式返回true,就執(zhí)行<c:otherwise>tag體,將結果送到輸出。
    在這個例子中,第一個<c:when>tag的test表達式是邏輯表達式:
    <c:when test="${cols > 0 && cols <= 10}">
    這里所用的變量cols是在上面討論的第一個<c:set>tag中定義的page屬性。如果所要求的列數(shù)在1到10之間,這個頁面就會產生一個顏色的table。否則(在<c:otherwise> tag中),這個頁面就顯示一個提示:
    <c:otherwise>
    <!-- Complain about unreasonable input -->
    ${cols} is an unreasonable number of columns.<p>
    Click <a href="index.jsp">here</a> to try again.
    </c:otherwise>
    在第一個<c:when>tag體內的是建table的代碼。<c:forEach>tag對table內的所有color迭代,把page屬性color賦給ColorScheme中的每個ColorBean:
    <c:if test="${(col % cols) == 0}">
    </TR><TR>
    </c:if>
    每個顏色名用它所代表的顏色打印出來,用表達式(${color.rgbHex})從color Bean得到顏色的hex表示。變量col在循環(huán)的末尾加1,以便正確分行:
    <c:set var="col" value="${col+1}"/>
    最后,循環(huán)在一行結束時用算術表達式和<c:if>tag強迫分行。
    上面的例子僅僅使我們對JSTL tag能做些什么有個初步印象。JSTL tag可以用來處理URL、傳遞請求、包含其他Web資源的內容、處理XML、創(chuàng)建國際化內容、執(zhí)行SQL查詢,還有很多。利用JSTL提供的強大的新工具可以使JSP的開發(fā)更容易。

    運行示例代碼
    下載以上兩個技巧的示例代碼的歸檔文件(http://java.sun.com/developer/EJTechTips/download/ttdec2003.war)。應用上下文的root是ttdec2003。下載的war文件還包含了這個示例應用的全部源代碼。
    你可以用deploytool程序或admin console在J2EE 1.4應用服務器上部署應用歸檔文件(ttdec2003.war)。你也可以用asadmin命令部署應用,如下所示:
    asadmin deploy install_dir/ttdec2003.war
    用war文件所在的目錄代替install_dir。
    可以用http:// ://localhost:8000/ttdec2003訪問應用。
    對于與J2EE 1.4兼容的其他應用服務器,用你所用的服務器部署工具把應用部署到你的平臺上。
    你應該在啟動應用時看到下面的頁面:


    posted @ 2006-03-09 11:10 hopeshared 閱讀(1072) | 評論 (0)編輯 收藏

    在本文寫作時,並無任何 SOAP 實作,能進行作業(yè)名稱的多載動作。這對使用 Java 的客戶端是很重要的,因為使用 Java 的伺服端所使用的介面,會利用 Java 的多載功能。但這對使用 COM 的客戶端倒無所謂,因為 COM 並不支援多載。

    <binding> 與 <operation> 元素
    Binding 區(qū)段是,指定通訊協(xié)定、序列化、與編碼的地方。若 Types、Messages、與 PortType 等區(qū)段負責抽象的資料內容,那麼 Binding 區(qū)段便負責處理資料傳輸?shù)木唧w細節(jié)。Binding 區(qū)段負責使前三個區(qū)段的抽象具體化。

    將繫結規(guī)格從資料與訊息宣告中分離出來的意義是,執(zhí)行相同業(yè)務的服務提供者,可將一組作業(yè) (portType) 標準化。若欲凸顯自身的差異,每個提供者可另外提供自訂繫結。讓 WSDL 擁有匯入 construct 是有好處的;因為如此一來,即可遠離 Bindings 與 Services 區(qū)段,將抽象定義置於自身的檔案中;並可將其散佈於服務提供者間,讓他們把抽象定義設定成標準。例如,銀行可標準化,一組抽象 WSDL 文件詳盡說明的銀行作業(yè)。但每家銀行還是可以自由地,「自訂」基礎通訊協(xié)定、序列最佳化、與編碼。

    下列為 Binding 區(qū)段的 WSDL 多載範例,於此重複以方便詳細討論:

    <binding name="fooSampleBinding" type="wsdlns:fooSamplePortType">
    <stk:binding preferredEncoding="UTF-8" />
    <soap:binding style="rpc"
    transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="foo">
    <soap:operation soapAction="http://tempuri.org/action/foo1"/>
    <input name="foo1">
    <soap:body use="encoded"
    namespace="http://tempuri.org/message/"
    encodingStyle=
    "http://schemas.xmlsoap.org/soap/encoding/" />
    </input>
    </operation>
    <operation name="foo">
    <soap:operation soapAction="http://tempuri.org/action/foo2"/>
    <input name="foo2">
    <soap:body use="encoded"
    namespace="http://tempuri.org/message/"
    encodingStyle=
    "http://schemas.xmlsoap.org/soap/encoding/" />
    </input>
    </operation>
    </binding>

    <binding> 元素會有個名稱 (本例中為「fooSampleBinding」),以方便 Services 區(qū)段的 <port> 元素參照。它有個參照 <portType> 的「type」屬性,在本例中為「wsdlns:fooSamplePortType」。第二行是 MSTK2 擴充元素 <stk:binding>,它可指定 preferredEncoding,或稱「UTF-8」。

    <soap:binding> 元素可指定,使用的樣式 (rpc) 與傳輸。傳輸屬性會參照命名空間,以確定所使用的 HTTP SOAP 通訊協(xié)定。

    有兩個 <operation> 元素具有相同的名稱「foo」。這兩個作業(yè)不同之處在於,兩個不同的 <input> 名稱:「foo1」與「foo2」。在兩個 <operation> 元素中,<soap:operation> 元素的「soapAction」屬性皆相同,都是一個 URI。soapAction 屬性是 SOAP 專屬的 URI,並逐字依 SOAP 訊息使用。以此方式取得的 SOAP 訊息,會有個 SOAPAction 標頭;而且還會以 <soap:operation> 元素中的 URI 為其值。雖然 HTTP 繫結需要 soapAction 屬性,但非 HTTP 繫結則不用。本文刊出時,其用途仍然不明。就本範例而言,它似乎可用來區(qū)別兩個不同的「foo」作業(yè)。SOAP 1.1 宣稱,soapAction 可用來識別訊息的「目的 (intent)」。它更建議伺服端,可用此屬性路由訊息,而不用剖析整個訊息。實務上,其用途差異很大。<soap:operation> 元素也可以含另一個名為「style」的屬性;若特定作業(yè)需要覆寫 <soap:binding> 元素中所指定的樣式,則可使用此屬性。

    <operation> 元素所含的 <input>、<output>、與 <fault> 元素,可對應 PortTypes 區(qū)段的相同元素。在上例中出現(xiàn)的只有 <input> 元素。在本例中,這三個元素都各有一個選擇性的「name」屬性,可用以區(qū)別名稱相同的作業(yè)。在範例的 <input> 元素中,有個 <soap:body> 元素,它可指定輸入結果 SOAP 訊息之 <body> 的內容。此元素有下列屬性:

    Use
    它是用以指定資料採「編碼 (encoded)」或「常值 (literal)」。「常值」的意義是,結果 SOAP 訊息所含資料的格式,完全依照抽象定義 (Types、Messages、與 PortTypes 區(qū)段) 的指定規(guī)格 。「編碼」的意義是,「encodingStyle」屬性 (參考下文) 會指定編碼方式。
    Namespace
    每個 SOAP 訊息的主體,都有自己的命名空間,以防止名稱衝突。此屬性所指定的 URI,會逐字使用於結果 SOAP 訊息之中。
    EncodingStyle
    以 SOAP 的編碼方式而言,URI 的值應該是「http://schemas.xmlsoap.org/soap/encoding」。
    文件樣式繫結
    在上一區(qū)段中,<soap:binding> 元素有個類型屬性被設定成「rpc」。若將此屬性設定成「document」,即可改變訊息在線上的排序。此時這些訊息便成了文件傳輸,而不再是函數(shù)簽章。在此繫結類型中,<message> 元素是定義文件格式,而非函數(shù)簽章。請參考下例中的 WSDL 片段:

    <definitions
    xmlns:stns="(SchemaTNS)"
    xmlns:wtns="(WsdlTNS)"
    targetNamespace="(WsdlTNS)">

    <schema targetNamespace="(SchemaTNS)"
    elementFormDefault="qualified">
    <element name="SimpleElement" type="xsd:int"/>
    <element name="CompositElement" type="stns:CompositeType"/>
    <complexType name="CompositeType">
    <all>
    <element name='a' type="xsd:int"/>
    <element name='b' type="xsd:string"/>
    </all>
    </complexType>
    </schema>

    <message...>
    <part name='p1' type="stns:CompositeType"/>
    <part name='p2' type="xsd:int"/>
    <part name='p3' element="stns:SimpleElement"/>
    <part name='p4' element="stns:CompositeElement"/>
    </message>
    ?</definitions>

    此結構描述有 SimpleElement 與 CompositeElement 兩個元素,以及一個宣告類型 (CompositeType)。所宣告的唯一 <message> 元素有四個部分 (part):p1 是 CompositeType 類型;p2 是 int 類型;p3 是 SimpleElement;而 p4 是 CompositeElement。下表是四種繫結的比較,依照「使用/類型」分別為:rpc/literal、document/literal、rpc/encoded、與 document/encoded。本表可說明,每種繫結方式反映在線上的實際情況。

    rpc / literal
    <operation name="method1" style="rpc" ...>
    <input>
    <soap:body parts="p1 p2 p3 p4"
    use="literal"
    namespace="(MessageNS)"/>
    </input>
    </operation>

    線上情形:
    <soapenv:body... xmlns:mns="(MessageNS)"
    xmlns:stns="(SchemaTNS)">
    <mns:method1>
    <mns:p1>
    <stns:a>123</stns:a>
    <stns:b>hello</stns:b>
    </mns:p1>
    <mns:p2>123</mns:p2>
    <mns:p3>

    <stns:SimpleElement>

    123

    </stns:SimpleElement>
    </mns:p3>
    <mns:p4>
    <stns:CompositeElement>
    <stns:a>123</stns:a>
    <stns:b>hello</stns:b>
    </stns:CompositeElement>
    </mns:p4>
    </mns:method1>
    </soapenv:body>
    document / literal / type=
    <operation name="method1"
    style="document" ...>
    <input>
    <soap:body parts="p1" use="literal">
    </input>
    </operation>

    線上情形:

    <soapenv:body... xmlns:stns="(SchemaTNS)">
    <stns:a>123</stns:a>
    <stns:b>hello</stns:b>
    </soapenv:body>

    rpc / encoded
    <operation name="method1" style="rpc" ...>
    <input>
    <soap:body parts="p1 p2" use="encoded"
    encoding=
    "http://schemas.xmlsoap.org/soap/encoding/"
    namespace="(MessageNS)"/>
    </input>
    </operation>

    線上情形:
    <soapenv:body... xmlns:mns="(MessageNS)">
    <mns:method1>
    <p1 TARGET="_self" HREF="#1"/>
    <p2>123</p2>
    </mns:method1>
    <mns:CompositeType id="#1">
    <a>123</a>
    <b>hello</b>
    </mns:CompositeType>
    </soapenv:body>
    document / literal / element=
    <operation name="method1"
    style="document" ...>
    <input>
    <soap:body parts="p3 p4"

    use="literal">
    </input>
    </operation>

    線上情形:

    <soapenv:body... xmlns:stns="(SchemaTNS)">
    <stns:SimpleElement>

    123

    </stns:SimpleElement>
    <stns:CompositeElement>
    <stns:a>123</stns:a>
    <stns:b>hello</stns:b>
    </stns:CompositeElement>
    </soapenv:body>

    document / encoded
    <operation name="method1"
    style="document" ...>
    <input>
    <soap:body parts="p1 p2" use="encoded"
    encoding=

    "http://schemas.xmlsoap.org/soap/encoding/"
    namespace="(MessageNS)"/>
    </input>
    </operation>

    線上情形:
    <soapenv:body... xmlns:mns="(MessageNS)">
    <mns:CompositeType>
    <a>123</a>
    <b>hello</b>
    </mns:CompositeType>
    <soapenc:int>123</soapenc:int>
    </soapenv:body>


    <service> 與 <port> 元素
    服務即是一組 <port> 元素。每個 <port> 元素,都以一對一的方式,關連一個位置與 <binding>。若有一個以上的 <port> 元素,與相同的 <binding> 關連,便可以使用其它 URL 作為替換。

    在 WSDL 文件中,可以有一個以上的 <service> 元素。多個 <service> 元素,可以有許多用途。其中之一便是,根據(jù) URL 的目的地,將傳輸埠群組化。因此,我只要使用另一個 <service>,就可以重新導向所有股票報價要求;而且我的客戶端程式依然可以正常運作,這是因為在這類的服務群組化中,通訊協(xié)定完全不會更動其它的服務。多個 <service> 服務的另一個用途是為了,根據(jù)基礎通訊協(xié)定,對傳輸埠進行分類。例如,可將所有的 HTTP 傳輸埠,置於一個 <service>;所有的 SMTP 傳輸埠置於另一個 <service>。客戶端便可根據(jù)它能處理的通訊協(xié)定,搜尋相對的 <service>。

    <service name="FOOService">
    <port name="fooSamplePort" binding="fooSampleBinding">
    <soap:address
    location="http://carlos:8080/fooService/foo.asp"/>
    </port>
    </service>

    在一份 WSDL 文件中,<service> 的「name」屬性,可區(qū)分出個別服務的不同。因為一個服務可能會有幾個傳輸埠,所以傳輸埠也必須有「name」屬性。

    總結
    本文已經說明了 WSDL 文件最顯著的 SOAP 特色。但應該聲明的是,WSDL 絕不僅只能在 HTTP 上說明 SOAP 而已。在說明 SOAP 上,WSDL 的表達能力絕對足以使用 HTTP-POST、HTTP-GET、SMTP、與其它通訊協(xié)定。只要使用 WSDL,不論是程式開發(fā)人員或一般使用者,都可輕鬆處理 SOAP。個人深信,WSDL 與 SOAP 的結合,將可引進全新的應用程式類別,以更徹底地利用各種網(wǎng)路服務。

    在 WSDL 的命名空間,有各種 XML 元素。下表整理了這些元素、屬性、與內容,以供參考:

    元素 屬性 內容 (子項)
    <definitions> name
    targetNamespace
    xmlns (其它命名空間) <types>
    <message>
    <portType>
    <binding>
    <service>
    <types> (無) <xsd:schema>
    <message> name <part>
    <portType> name <operation>
    <binding> name
    type <operation>
    <service> name <port>
    <part> name
    type (空值)
    <operation> name
    parameterOrder <input>
    <output>
    <fault>
    <input> name
    message (空值)
    <output> name
    message (空值)
    <fault> name

    message (空值)
    <port> name
    binding <soap:address>

    資源:
    WSDL 1.1
    SOAP 1.1
    XML 結構描述入門
    MS SOAP Toolkit 下載網(wǎng)站
    IDL 至 WSDL 的轉譯工具
    含 WSDL 至 VB 之 Proxy 產生器的免費網(wǎng)路資源
    PocketSOAP:SOAP 之相關元件、工具、與原始程式碼


    原文地址:http://stu.timeover.net/article.php?articleid=842
    posted @ 2006-03-09 10:25 hopeshared 閱讀(1227) | 評論 (0)編輯 收藏

    僅列出標題
    共30頁: First 上一頁 17 18 19 20 21 22 23 24 25 下一頁 Last 
    主站蜘蛛池模板: 国产精品偷伦视频观看免费| 色妞www精品视频免费看| 一级毛片成人免费看免费不卡 | 亚洲精品乱码久久久久久蜜桃图片| 亚洲美女免费视频| 亚洲综合亚洲国产尤物| 亚洲毛片免费观看| 亚洲成年网站在线观看| 永久免费bbbbbb视频| 久久久久亚洲精品无码网址色欲| 四虎永久成人免费影院域名| 美女18毛片免费视频| 伊人久久大香线蕉亚洲| 久久久免费的精品| 亚洲图片中文字幕| 免费看大黄高清网站视频在线| 国产精品无码亚洲精品2021| 亚洲精品偷拍视频免费观看| 99精品视频免费| 日本久久久久亚洲中字幕| 国产福利在线免费| 亚洲AV香蕉一区区二区三区| 亚洲精品无码久久久| 99热免费在线观看| 亚洲中文字幕无码亚洲成A人片| 四虎影视在线永久免费看黄| 国产免费久久精品丫丫| 亚洲国产精品综合一区在线| 免费国产在线观看| 99re视频精品全部免费| 亚洲色偷偷偷综合网| 亚洲一区二区三区无码影院| 最近2022中文字幕免费视频| 亚洲欧洲精品成人久久曰| 亚洲日韩在线第一页| 亚洲一区在线免费观看| 牛牛在线精品免费视频观看| 亚洲人成在线影院| 免费国产不卡午夜福在线| 99久久免费观看| 少妇亚洲免费精品|