WSDL文件簡介(附例子)

本文介紹瞭如何編寫一個簡單的WSDL文件,並根據WSDL文件編寫服務器端和客戶端代碼,併發布Web Service服務的過程。
首先明確的一點是WSDL現在有兩個版本,分別爲WSDL 1.1和WSDL 2.0,W3C的官方文檔地址分別爲:
http://www.w3.org/TR/wsdl
Web Services Descrīption Language (WSDL) 1.1
W3C Note 15 March 2001

http://www.w3.org/TR/2007/WD-wsdl20-primer-20070326/
Web Services Descrīption Language (WSDL) Version 2.0 Part 0: Primer
W3C Working Draft 26 March 2007

其中很多應用還是以版本1.1爲基礎實現。下面是2.0與1.1的區別:
Adding further semantics to the descrīption language.
Removal of message constructs.
No support for operator overloading.
PortTypes renamed to interfaces.
Ports renamed to endpoints.

下面是一些常見的命名空間:
prefix namespace URI
wsdl http://schemas.xmlsoap.org/wsdl/
soap http://schemas.xmlsoap.org/wsdl/soap/
http http://schemas.xmlsoap.org/wsdl/http/
mime http://schemas.xmlsoap.org/wsdl/mime/
soapenc http://schemas.xmlsoap.org/soap/encoding/
soapenv http://schemas.xmlsoap.org/soap/envelope/
xsi http://www.w3.org/2000/10/XMLSchema-instance
xsd http://www.w3.org/2000/10/XMLSchema
tns (various)

對於WSDL規範,可以參考以上兩個官方文檔,本文主要介紹如何編寫WSDL文檔(其實官方文檔中已經給出了很多例子和方法,這裏只是簡單的翻譯與重複介紹)。

下面舉例說明如何編寫WSDL文檔:
我們做一個非常簡單的加法運算服務:客戶端傳入SOAP請求消息,包含兩個加數,然後在服務器端獲取這兩個加數,求和,然後返回給客戶端。
請求消息和響應消息結構分別如下(有效負載部分,外層的SOAP封裝AXIS2會自動添加上去):
request:
<SumRequest>
<First>15</First>
<Second>16</Second>
</SumRequest>

response:
<SumResponse>
<Result>31</Result>
</SumResponse>

1.首先需要進行定義的就是soap消息的數據類型,無疑,這裏需要定義兩個複雜的數據類型:
SumRequest
SumResponse
它們分別包含有子元素First、Second和Result.
另外還需要定義一種異常,這裏我們定義成爲SumFault,比如傳入的兩個加數的和超出了xsd:int的範圍時,拋出該異常。
(注意,很多代碼生成器都會根據WSDL生成代碼,將SumFault部分生成爲後綴爲Exception的異常類。)

2.定義數據類型的目的是爲傳入傳出消息做準備的,傳入傳出消息的定義方式使用message元素來定義。
我們定義三種消息:SumRequest,SumResponse以及SumFault,分別爲請求消息,響應消息以及出錯時的消息。

3.定義好了傳入傳出消息後,就要定義一個portType,該節點類型定義了主要的業務操作。
4.接着將定義SOAP綁定:
SumSoapBinding:爲SumService端口類型所定義的操作和消息指定具體傳輸中所使用的消息格式和協議細節。綁定的方式爲SOAP,傳輸方式爲http,消息的格式爲document。
5.定義Web服務:Web服務名爲SumService。
6.本Web服務的操作爲Sum操作。
7.端口爲:爲SumSoapBing綁定指定一個地址來定義服務訪問點。

根據以上七個部分編寫完成的WSDL文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.zzl.org/Sum"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.zzl.org/Sum">
<wsdl:documentation>
The WSDL file of SumService.
</wsdl:documentation>
<wsdl:types>
<wsdl:documentation>
Data types that are used for request and response messages.
</wsdl:documentation>
<xsd:schema targetNamespace="http://www.zzl.org/Sum">
<xsd:element name="SumRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="First" type="xsd:int" />
<xsd:element name="Second" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="SumResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Result" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="SumFault">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Code" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="SumRequest">
<wsdl:documentation>
The data that will be transmitted to the service.
</wsdl:documentation>
<wsdl:part element="tns:SumRequest" name="request" />
</wsdl:message>
<wsdl:message name="SumResponse">
<wsdl:documentation>
The data that will be returned to the client.
</wsdl:documentation>
<wsdl:part element="tns:SumResponse" name="response" />
</wsdl:message>

<wsdl:message name="SumFault">
<wsdl:documentation>
The fault that will be thrown when fault occurs.
</wsdl:documentation>
<wsdl:part name="axisFault" element="tns:SumFault" />
</wsdl:message>
<wsdl:portType name="SumService">
<wsdl:documentation>
The SumService contains the business operation.
</wsdl:documentation>
<wsdl:operation name="RevokeCert">
<wsdl:documentation>
The operation that do the business work.
</wsdl:documentation>
<wsdl:input message="tns:SumRequest" />
<wsdl:output message="tns:SumResponse" />
<wsdl:fault name="fault" message="tns:SumFault" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SumSoapBinding" type="tns:SumService">
<wsdl:documentation>
The SumSoapBinding defines the SOAP message format and
protocol details for Sum operation and messages defined by a
RevokeService portType.
</wsdl:documentation>
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Sum">
<soap:operation soapAction="urn:Sum" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="fault">
<soap:fault use="literal" name="fault" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SumService">
<wsdl:documentation>
SumService provides the service of summing.
</wsdl:documentation>
<wsdl:port binding="tns:SumSoapBinding" name="SumSoapBinding">
<wsdl:documentation>
The port defines the endpoint by specifying a soap
address for SumSoapBinding.
</wsdl:documentation>
<soap:address location="http://www.zzl.org/ExampleService/services/SumService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

服務器端和客戶端的代碼是根據WSDL文件編寫出來的,這纔是正確的過程,但是,在國內的軟件開發過程,常常是先寫代碼,再根據代碼生成WSDL文件,這是不正確的。

編寫服務器端的程序如下:
1. 建立工程ExampleService.如下圖所示:

2. 編寫服務器端代碼:
SumService.java

package org.zzl.service;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;

/**
* The Web Service class SumService which implement add two number and return
* the result.
*
* @author [email protected]
* @version 0.7
*/
public class SumService {
/**
* The request soap message object.
*/
private OMElement requestSoap = null;

/**
* First addend.
*/
private static final String FIRST = "First";

/**
* Second addend.
*/
private static final String SECOND = "Second";

/**
* Sum Response element.
*/
private static final String SUM_RESPONSE = "SumResponse";

/**
* Result element.
*/
private static final String SUM = "Result";

public OMElement Sum(OMElement soap) throws AxisFault {
requestSoap = soap;
OMElement first=
requestSoap.getFirstChildWithName(new QName(FIRST));
OMElement second =
requestSoap.getFirstChildWithName(new QName(SECOND));
int sum = Integer.parseInt(first.getText())
+ Integer.parseInt(second.getText());
return getResponse(sum);
}

/**
* Get the SOAP response message.
*
* @param sum
* The adding result.
* @return The SOAP response message.
*/
private OMElement getResponse(int sum) {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace ōmNs = factory.createOMNamespace("", "");
OMElement response = factory.createOMElement(SUM_RESPONSE, omNs);
OMElement sumElement = factory.createOMElement(SUM, omNs);
sumElement.setText(String.valueOf(sum));
response.addChild(sumElement);
return response;
}
}

編寫客戶端代碼:
TestSumService.java

package org.zzl.service.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class TesSumService{
private static EndpointReference targetEPR = new EndpointReference(
"http://localhost/axis2/services/SumService");

public static void main(String[] args) throws FileNotFoundException,
FactoryConfigurationError, XMLStreamException {
OMElement requestSoapMessage =
getSoapRequestMessage("data/request.xml");
Options ōptions = new Options();
options.setAction("urn:Sum");
options.setTo(targetEPR);
ServiceClient sender = null;
try {
sender = new ServiceClient();
sender.setOptions(options);
System.out.println(sender.sendReceive(requestSoapMessage)
.toStringWithConsume());
} catch (AxisFault e) {
System.out.println(e.getMessage());
}
}

public static OMElement getSoapRequestMessage(String filePath)
發佈了31 篇原創文章 · 獲贊 1 · 訪問量 1303
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章