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

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

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

    Hello World
    Java技術學習
    posts - 17,  comments - 7,  trackbacks - 0
    Web Service描述語言 WSDL 詳解 2

    SOAP消息

      對于使用WSDL的客戶機和服務機來說,研究WSDL文件的一種方法就是決定什么來接受所發送的信息。盡管SOAP使用底層協議,如IP和HTTP等,但應用程序決定了服務器與客戶機之間交互的高級協議。也就是說,進行一項操作,比如"echoint"把輸入的整數送回,參數的數目、每個參數的類型、以及參數如何傳送等因素決定了應用程序特定的協議。有很多方法可以確定此類協議,但我相信最好的方法就是使用WSDL。如果我們用這種視角來看待它,WSDL不只是一種接口協議,而且是一種協議特定的語言。它就是我們超越"固定"協議(IP、HTTP等)所需要的應用程序特定協議。

      WSDL可以確定SOAP消息是否遵從RPC或文檔風格。RPC風格的消息(就是示例中所用的)看起來像是函數調用。而文檔風格的消息則更普通,嵌套層次更小。下面的XML消息就是示例WSDL文件解析后的發送/接受效果,解析使用的是MS SOAP Toolkit 2.0(MSTK2)中的SoapClient對象。

      從客戶端調用"foo(5131953)"函數:

    <?xml?version="1.0"?encoding="UTF-8"?standalone="no"?>
     
    <SOAP-ENV:Envelope?
      
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
      xmlns:SOAP-ENV
    ="http://schemas.xmlsoap.org/soap/envelope/">
     
    <SOAP-ENV:Body>
      
    <m:foo?xmlns:m="http://tempuri.org/message/">
       
    <arg>5131953</arg>
      
    </m:foo>
     
    </SOAP-ENV:Body>
     ?
    </SOAP-ENV:Envelope>
     從服務器接受的信息:
      
    <?xml?version="1.0"?encoding="UTF-8"?standalone="no"?>
    <SOAP-ENV:Envelope?
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
    xmlns:SOAP-ENV
    ="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
    <SOAPSDK1:fooResponse?xmlns:SOAPSDK1="http://tempuri.org/message/">
    <result>5131953</result>
    </SOAPSDK1:fooResponse>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

      兩函數都調用了消息,其回應是有效的XML。SOAP消息由幾部分組成,首先是<Envelop>元素,包含一個可選的<Header>元素以及至少一個<body>元素。Rpc函數所調用的消息體有一個根據操作"foo"命名的元素,而回應信息體有一個"fooResponse"元素。Foo元素有一個部分<arg>,就和WSDL中描述的一樣,是單參數的。fooResponse也相應的有一個<result>的部分。注意encodingStyle、envelope和message的namespace和WSDL Bindings欄中的預定義的一致,重復如下:
    <binding?name="SimpleBinding"?type="wsdlns:SimplePortType">
    <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/Simple.foo"/>
    <input>
    <soap:body?use="encoded"?
    namespace
    ="http://tempuri.org/message/"?
    encodingStyle
    =
    "http://schemas.xmlsoap.org/soap/encoding/"
    ?/>
    </input>
    <output>
    <soap:body?use="encoded"?
    namespace
    ="http://tempuri.org/message/"?
    encodingStyle
    =
    "http://schemas.xmlsoap.org/soap/encoding/"
    ?/>
    </output>
    </operation>
    </binding>

    WSDL的Types欄和Messages欄中的XML Schema
    WSDL數據類型是基于"XML Schema: Datatypes"(XSD)的,現在已經被W3C推薦。這一文檔共有三個版本(1999,2000/10,2001),因此必須在namespace屬性的<definitions>元素中指明所使用的是哪一個版本。
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
    在本文中,我將只考慮2001版本。WSDL標準的推薦者強烈建議使用2001版。

      在本欄和以后各部分,需使用以下簡縮或前綴

    前綴代表的Namespace描述
    Soapenchttp://schemas.xmlsoap.org/soap/encodingSOAP 1.1 encoding
    Wsdlhttp://schemas.xmlsoap.org/wsdl/soapWSDL 1.1
    Xsd http://www.w3.org/2001/XMLSchemaXML Schema

      XSD基類型

      下表是直接從MSTK2文檔中取出的,列舉了MSTK2所支持的所有XSD基類型。它也告訴在客戶端或服務器端的WSDL讀取程序如何把XSD類型映射到在VB、C++和IDL中相應的類型。

    XSD (Soap)類型變量類型 VBC++IDLComments
    anyURIVT_BSTRStringBSTRBSTR?
    base64Binary VT_ARRAY | VT_UI1Byte()SAFEARRAYSAFEARRAY(unsigned char)?
    BooleanVT_BOOL Boolean VARIANT_BOOLVARIANT_BOOL?
    ByteVT_I2Integershortshort轉換時驗證范圍有效性
    DateVT_DATEDateDATEDATE時間設為 oo:oo:oo
    DateTimeVT_DATEDateDATEDATE?
    DoubleVT_R8Doubledoubledouble?
    DurationVT_BSTRStringBSTRBSTR不轉換和生效
    ENTITIESVT_BSTRStringBSTRBSTR不轉換和生效
    ENTITYVT_BSTRStringBSTRBSTR不轉換和生效
    FloatVT_R4Singlefloatfloat?
    GDayVT_BSTRStringBSTRBSTR不轉換和生效
    GMonthVT_BSTRStringBSTRBSTR不轉換和生效
    GMonthDayVT_BSTRStringBSTRBSTR不轉換和生效
    GYearVT_BSTRStringBSTRBSTR不轉換和生效
    GYearMonthVT_BSTRStringBSTRBSTR不轉換和生效
    IDVT_BSTRStringBSTRBSTR不轉換和生效
    IDREFVT_BSTRStringBSTRBSTR不轉換和生效
    IDREFSVT_BSTRStringBSTRBSTR不轉換和生效
    IntVT_I4Longlonglong?
    IntegerVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    LanguageVT_BSTRStringBSTRBSTR不轉換和生效
    LongVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    NameVT_BSTRStringBSTRBSTR不轉換和生效
    NCNameVT_BSTRStringBSTRBSTR不轉換和生效
    negativeIntegerVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    NMTOKENVT_BSTRStringBSTRBSTR不轉換和生效
    NMTOKENSVT_BSTRStringBSTRBSTR不轉換和生效
    nonNegativeIntegeVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    nonPositiveIntegerVT_DECIMALVariantDECIMADECIMAL轉換時范圍生效
    normalizedStringVT_BSTRStringBSTRBSTR?
    NOTATIONVT_BSTRStringBSTRBSTR不轉換和生效
    NumberVT_DECIMALVariantDECIMALDECIMAL?
    positiveIntegerVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    QnameVT_BSTRStringBSTRBSTR不轉換和生效
    ShortVT_I2Integershortshort?
    StringVT_BSTR StringBSTRBSTR?
    TimeVT_DATEDateDATEDATE日設為1899年12月30日
    TokenVT_BSTRStringBSTRBSTR不轉換和生效
    unsignedByteVT_UI1Byteunsigned charunsigned char?
    UnsignedIntVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    unsignedLongVT_DECIMALVariantDECIMALDECIMAL轉換時范圍生效
    unsignedShortVT_UI4LongLongLong轉換時范圍生效

      XSD定義了兩套內建的數據類型:原始的和派生的。在下文中查閱內建數據類型的層次十分有益:
    http://www.w3.org/TR/2001/PR-xmlschema-2-20010330?

    complex類型

      XML schema允許complex類型的定義,就像C里是struct。例如,為了定義類似如下的C的struct類型:
    typedef?struct?{
     
    string?firstName;
     
    string?lastName;
     
    long?ageInYears;
     
    float?weightInLbs;
     
    float?heightInInches;
    }?PERSON;

    我們可以寫XML schema:
    <xsd:complexType?name="PERSON">
    <xsd:sequence>
     
    <xsd:element?name="firstName"?type="xsd:string"/>
     
    <xsd:element?name="lastName"?type="xsd:string"/>
     
    <xsd:element?name="ageInYears"?type="xsd:int"/>
     
    <xsd:element?name="weightInLbs"?type="xsd:float"/>
     
    <xsd:element?name="heightInInches"?type="xsd:float"/>
    </xsd:sequence>
    </xsd:complexType>
      不過,complex類型可以表達比struct更多的信息。除了<sequence>以外,它還可以有其他的子元素,比如<all>
    <xsd:complexType?name="PERSON">
    <xsd:all>
     
    <xsd:element?name="firstName"?type="xsd:string"/>
     
    <xsd:element?name="lastName"?type="xsd:string"/>
     
    <xsd:element?name="ageInYears"?type="xsd:int"/>
     
    <xsd:element?name="weightInLbs"?type="xsd:float"/>
     
    <xsd:element?name="heightInInches"?type="xsd:float"/>
    </xsd:all>
    </xsd:complexType>?

    這意味著<element>的成員變量可以以任何順序排列,每一個都是可選的。這和C中的struct類型不太一樣。

      注意內建數據類型string, int, float。C的string也是XML的string,float也類似。但C中的long類型在XML中是int(上表中)。

      在WSDL文件中,像上面的complex類型可以在Types欄聲明。例如,我可以用以下方式聲明PERSON類型并用在Messages欄。

    <?xml?version="1.0"?encoding="UTF-8"??>
    <definitions?…?>
    <types>
    <schema?targetNamespace="someNamespace"?
    xmlns:typens
    ="someNamespace"?>
    <xsd:complexType?name="PERSON">
    <xsd:sequence>
     
    <xsd:element?name="firstName"?type="xsd:string"/>
     
    <xsd:element?name="lastName"?type="xsd:string"/>
     
    <xsd:element?name="ageInYears"?type="xsd:int"/>
     
    <xsd:element?name="weightInLbs"?type="xsd:float"/>
     
    <xsd:element?name="heightInInches"?type="xsd:float"/>
    </xsd:sequence>
    </xsd:complexType>
    </schema>
    </types>

    <message?name="addPerson">
     
    <part?name="person"?type="typens:PERSON"/>
    </message>

    <message?name="addPersonResponse">
     
    <part?name="result"?type="xsd:int"/>
    </message>
    </definitions>?

      上例中第一個消息由"adperson",并且有一個<part>,其類型為"PERSON"。PERSON類型是在Types欄聲明的。

      如果我們使用完整的WSDL文件包含以上的部分,并以之初始化MSTK2 SoapClient,它將成功的解析該文件。當然,它不會去調用<addPerson>。這是因為SoapClient本身并不知道如何處理complex類型,它需要定制類型映射來處理complex類型。MSTK2文檔中有包含定制類型映射的示例。

      還有另一種方法可以把<part>元素聯系到類型聲明。這就是使用元素。下例中我將Types欄中聲明兩個元素("Person"和"Gendr"),然后我將在"addPerson"<message>中使用元素屬性來引用它們。

    <?xml?version="1.0"?encoding="UTF-8"??>
    <definitions?…?>
    <types>
    <schema?targetNamespace="someNamespace"?
     xmlns:typens
    ="someNamespace"?>
    <element?name="Person">
    <xsd:complexType>
     
    <xsd:sequence>
      
    <xsd:element?name="firstName"?type="xsd:string"/>
      
    <xsd:element?name="lastName"?type="xsd:string"/>
      
    <xsd:element?name="ageInYears"?type="xsd:int"/>
      
    <xsd:element?name="weightInLbs"?type="xsd:float"/>
      
    <xsd:element?name="heightInInches"?type="xsd:float"/>
     
    </xsd:sequence>
    </xsd:complexType>
    </element>
    <element?name="Gender">
    <xsd:simpleType>
     
    <xsd:restriction?base="xsd:string">
      
    <xsd:enumeration?value="Male"?/>
      
    <xsd:enumeration?value="Female"?/>
     
    </xsd:restriction>
    </xsd:simpleType>
    </element>
    </schema>
    </types>

    <message?name="addPerson">
     
    <part?name="who"?element="typens:Person"/>
     
    <part?name="sex"?element="typens:Gender"/>
    </message>

    <message?name="addPersonResponse">
     
    <part?name="result"?type="xsd:int"/>
    </message>
    </definitions>?

      Types欄中的Gender<element>里嵌入了枚舉類型,其枚舉值為"Male""Female"。然后我又在"addPerson"<message>中通過元素屬性而不是類型屬性來引用它。

      "元素屬性"和"類型屬性"在把某特定類型關聯到<part>時有什么不同呢?使用元素屬性,我們可以描述一個部分,它可以假定幾個類型(就像變量一樣),而是用類型屬性我們就無法這樣做。下例說明了這一點。

    <?xml?version="1.0"?encoding="UTF-8"??>
    <definitions?…?>
    <types>
    <schema?targetNamespace="someNamespace"?
    xmlns:typens
    ="someNamespace">
    <xsd:complexType?name="PERSON">
     
    <xsd:sequence>
      
    <xsd:element?name="firstName"?type="xsd:string"/>
      
    <xsd:element?name="lastName"?type="xsd:string"/>
      
    <xsd:element?name="ageInYears"?type="xsd:int"/>
      
    <xsd:element?name="weightInLbs"?type="xsd:float"/>
      
    <xsd:element?name="heightInInches"?type="xsd:float"/>
     
    </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType?name="femalePerson">
    <xsd:complexContent>
     
    <xsd:extension?base="typens:PERSON"?>
     
    <xsd:element?name="favoriteLipstick"?type="xsd:string"?/>
    </xsd:extension>
    </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType?name="malePerson">
    <xsd:complexContent>
    <xsd:extension?base="typens:PERSON"?>
    <xsd:element?name="favoriteShavingLotion"?type="xsd:string"?/>
    </xsd:extension>
    </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType?name="maleOrFemalePerson">
    <xsd:choice>
     
    <xsd:element?name="fArg"?type="typens:femalePerson"?>
     
    <xsd:element?name="mArg"?type="typens:malePerson"?/>
    </xsd:choice>
    </xsd:complexType>
    </schema>
    </types>

    <message?name="addPerson">
     
    <part?name="person"?type="typens:maleOrFemalePerson"/>
    </message>

    <message?name="addPersonResponse">
     
    <part?name="result"?type="xsd:int"/>
    </message>
    </definitions>?

      上例也告訴我們extension的派生。"femailPerson"和"malePerson"都是從"PERSON"派生出來的。它們各有一些額外的元素:"femalePerson"有"favoriteLipstick"元素,"malePerson"有"favoriteShavingLotion"元素。兩派生類型都歸入一個complex類型"maleOrFemalePerson",使用的是<choice>構造。最后,在"adperson"<message>中,新類型有"person"<part>引用。這樣,參數或<part>就可以是"femalePerson"或"malePerson"了。

    數組
      XSD提供<list>結構來聲明一個數組,元素之間有空格界定。不過SOAP不是使用XSD來編碼數組的,它定義了自己的數組類型--"SOAP-ENC: Array"。下列的例子揭示了從這一類型派生出一位整數數組的方法:

    <xsd:complexType?name="ArrayOfInt">
    <xsd:complexContent>
     
    <xsd:restriction?base="soapenc:Array">
      
    <attribute?ref="soapenc:arrayType"?wsdl:arrayType="xsd:int[]"/>
     
    </xsd:restriction>
    </xsd:complexContent>
    </xsd:complexType>

      新的complex類型從soapenc:array限制派生。然后又聲明了complex類型的一個屬性。引用"soapenc:arrayType"實際上是這樣完成的:

    <xsd:attribute?name="arrayType"?type="xsd:string"/>

    wsdl:arrayType屬性值決定了數組每個成員的類型。數組的成員也可以是Complex類型。:

    <xsd:complexType?name="ArrayOfPERSON">
    <xsd:complexContent>
    <xsd:restriction?base="soapenc:Array">
    <attribute?ref="soapenc:arrayType"?
    wsdl:arrayType
    ="typens:PERSON[]"/>
    </xsd:restriction>
    </xsd:complexContent>
    </xsd:complexType>?

      WSDL要求數組的類型由"ArrayOf"和每個數組元素的類型串聯而成。很顯然,顧名思義,"ArrayOfPERSON"是PERSON結構的數組。下面我將使用ArrayOfPERSON來聲明一個<message>,并加入不止一個PERSON:

    <?xml?version="1.0"?encoding="UTF-8"??>
    <definitions?…?>
    <types>
    <schema?targetNamespace="someNamespace"?
    xmlns:typens
    ="someNamespace"?>
    <xsd:complexType?name="PERSON">
     
    <xsd:sequence>
      
    <xsd:element?name="firstName"?type="xsd:string"/>
      
    <xsd:element?name="lastName"?type="xsd:string"/>
      
    <xsd:element?name="ageInYears"?type="xsd:int"/>
      
    <xsd:element?name="weightInLbs"?type="xsd:float"/>
      
    <xsd:element?name="heightInInches"?type="xsd:float"/>
     
    </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType?name="ArrayOfPERSON">
    <xsd:complexContent>
    <xsd:restriction?base="soapenc:Array">
    <attribute?ref="soapenc:arrayType"?
    wsdl:arrayType
    ="typens:PERSON[]"/>
    </xsd:restriction>
    </xsd:complexContent>
    </xsd:complexType>
    </schema>
    </types>

    <message?name="addPersons">
     
    <part?name="person"?type="typens:ArrayOfPERSON"/>
    </message>

    <message?name="addPersonResponse">
     
    <part?name="result"?type="xsd:int"/>
    </message>

    </definitions>


    ?

    posted on 2007-01-22 12:37 Java初心 閱讀(1410) 評論(0)  編輯  收藏 所屬分類: Web Service

    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 欧美色欧美亚洲另类二区| 亚洲av无码潮喷在线观看| 亚洲精品乱码久久久久久不卡| 亚洲国产精品成人久久蜜臀 | 亚洲a无码综合a国产av中文| 美女黄色毛片免费看| 成人av片无码免费天天看| 久久精品免费观看国产| 在线视频免费观看高清| 免费一级国产生活片| 国产亚洲一区二区精品| 亚洲Av高清一区二区三区| 美女裸免费观看网站| 中文字幕无码日韩专区免费| 国产在线jyzzjyzz免费麻豆| 日日操夜夜操免费视频| 亚洲精品无码AV人在线播放 | 亚洲av不卡一区二区三区| 亚洲av乱码一区二区三区| 免费无码午夜福利片| 99蜜桃在线观看免费视频网站| 成人性生交大片免费看午夜a| 亚洲国产精品无码久久久久久曰 | 久久精品国产96精品亚洲| 亚洲中文字幕乱码一区| fc2成年免费共享视频网站| 麻花传媒剧在线mv免费观看| 国产免费小视频在线观看| 亚洲av福利无码无一区二区| 亚洲а∨天堂久久精品9966| eeuss免费天堂影院| www.黄色免费网站| 久久精品国产精品亚洲艾草网美妙| 久久久亚洲裙底偷窥综合| 老湿机一区午夜精品免费福利| 久久国产精品2020免费m3u8| 国产乱子伦精品免费女| 亚洲精品在线观看视频| 在线91精品亚洲网站精品成人| 99re免费在线视频| 亚洲日韩在线中文字幕第一页|