2017年1月15日 星期日

架設CXF、WSDL格式、SOAP格式 ( WebService 二)

※架設CXF

apache官網下載CXF框架,下載ZIP的
然後將lib裡面的jar檔通通複製到專案裡
啟動server的程式碼和上一篇一樣,但Console不太一樣了

本來只有黑色的字,現在會發現有jetty和cxf的字

啟動server的Endpoint.publish的回傳值,用JDK是「com.sun.xml.internal.ws.transport.http.server.EndpointImpl」,但用了CXF後會變成「org.apache.cxf.jaxws.EndpointImpl」

JDK是不能回傳Map的,我用java8都還是不行;在啟動伺服器端的程式時,會報「GetXXXResponse do not have a property of the name return」,但用CXF是可以的,但此時用wsimport生成的程式碼,回傳的不是Map,寫test時用法如下:

HelloWSService hws = new HelloWSService();
IHelloWS hw = hws.getHelloWSPort();
    
Return map = hw.getMap();
List<Entry> entry = map.getEntry(); // map.entry
for (Entry e : entry) {
    System.out.println(e.getKey());
    System.out.println(e.getValue());
}

※map.entry和map.getEntry()都可以,但map.entry是protected;map.getEntry()是public,


在下載下來的資料夾裡,有個bin資料夾,裡面都是一些轉換的工具,這裡使用wsdl2java,當然要先在環境變數裡設定,用法和JDK的差不多,雖然用法可以用wsdl2java -h,但還可以看官網的表格比較清楚

此時下wsdl2java -d D:\xxx http://localhost:8888/aaa/bbb/ccc?wsdl,不用加-keep就有java檔了,其他測試方法和上一篇一樣,如果不想加-d就先切換到想生成的路徑

但此時還有一個地方不太一樣,就是wsdl的格式稍有不同
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://test.hello/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloWSService" targetNamespace="http://test.hello/">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.hello/" elementFormDefault="unqualified" targetNamespace="http://test.hello/" version="1.0">
            <xs:element name="add" type="tns:add"/>
            <xs:element name="addResponse" type="tns:addResponse"/>
            <xs:element name="hello" type="tns:hello"/>
            <xs:element name="helloResponse" type="tns:helloResponse"/>
            <xs:complexType name="hello">
                <xs:sequence/>
            </xs:complexType>
            <xs:complexType name="helloResponse">
                <xs:sequence/>
            </xs:complexType>
            <xs:complexType name="add">
                <xs:sequence>
                    <xs:element minOccurs="0" name="arg0" type="xs:int"/>
                    <xs:element name="arg1" type="xs:int"/>
                </xs:sequence>
            </xs:complexType>
            <xs:complexType name="addResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="return" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="hello">
        <wsdl:part element="tns:hello" name="parameters"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="helloResponse">
        <wsdl:part element="tns:helloResponse" name="parameters"></wsdl:part>
    </wsdl:message>
        <wsdl:message name="addResponse">
        <wsdl:part element="tns:addResponse" name="parameters"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="add">
        <wsdl:part element="tns:add" name="parameters"></wsdl:part>
    </wsdl:message>
    <wsdl:portType name="IHelloWS">
        <wsdl:operation name="hello">
            <wsdl:input message="tns:hello" name="hello"></wsdl:input>
            <wsdl:output message="tns:helloResponse" name="helloResponse"></wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="add">
            <wsdl:input message="tns:add" name="add"></wsdl:input>
            <wsdl:output message="tns:addResponse" name="addResponse"></wsdl:output>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="HelloWSServiceSoapBinding" type="tns:IHelloWS">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="hello">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="hello">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="helloResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="add">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="add">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="addResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="HelloWSService">
        <wsdl:port binding="tns:HelloWSServiceSoapBinding" name="HelloWSPort">
            <soap:address location="http://localhost:8888/aaa/bbb/ccc"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

※types下的schema本來是import的,現在直接寫出來了



※WSDL格式

<definitions>
    <types>
        <xsd:schema>
            <xsd:import />(裡面是<element>)
        </xsd:schema>
    </types>
    <message>
        <part />
    </message>
    <message>
        <part />
    </message>
    <portType>
        <operation>
            <input />
            <output />
        </operation>
    </portType>
    <binding>
        <soap:binding />
        <operation>
            <soap:operation />
            <input>
                <soap:body />
            </input>
            <output>
                <soap:body />
            </output>
        </operation>
    </binding>
    <service>
        <port>
            <soap:address />
        </port>
    </service>
</definitions>

※必須有XML schema 基礎

※types:定義XML約束,方法的名稱、參數、回傳值
message:一個方法會有兩個,會對應到types裡的約束
portType:介面類型
binding:綁定介面的實作
service:一組服務

※從service開始由下往上,一層一層解析

※types > schema > element
message > part          part連到element
portType > operation > input/ouput          input/output連到message
binding > operation > input/output          bingding連到portType
service > port > addrress          port連到binding
由service的name屬性開始解析



※SOAP格式

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://test.hello/">
    <soapenv:Header/>
    <soapenv:Body>
        <test:add>
            <arg0></arg0>
            <arg1></arg1>
        </test:add>
    </soapenv:Body>
</soapenv:Envelope>
--------------------
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns2:addResponse xmlns:ns2="http://test.hello/">
            <return>Answer is 100</return>
        </ns2:addResponse>
    </soap:Body>
</soap:Envelope>

※從WSDL解析出來的XML,可以讓java做轉換

※上面是Request;下面是Response

※基本上很像HTML,HTML下有HEAD和BODY;SOAP是ENVELOPE下有HEADER和BODY,BODY裡有請求的方法或回傳值


沒有留言:

張貼留言