首先咱們來建立一個用於對外發布的WebService類java
//此註解代表該類是一個WebService,可用於發佈WebService服務 @WebService public class PhoneService { public Phone getPhoneInfo(String name) { Phone phone = new Phone(); phone.setName(name); if (name.endsWith("android")) { phone.setProduce("Oracle"); phone.setTime(new Date()); } else if (name.endsWith("apple")) { phone.setProduce("Apple"); phone.setTime(new Date()); } else { phone.setProduce("未知"); phone.setTime(new Date()); } return phone; } }
發佈該服務:android
public static void main(String[] args) { //WebService發佈的地址,端口號和路徑隨意寫,IP地址在實際應用時應該寫發佈WebService的服務器的地址 String address = "http://127.0.0.1:7777/wwss/phoneService"; Endpoint endpoint = Endpoint.publish(address, new PhoneService()); //這裏能夠手動中止該服務,可是在實際開發中也不會隨意中止 // endpoint.stop(); System.out.println(address + "?WSDL"); }
而後打開瀏覽器,輸入以上發佈的地址:http://127.0.0.1:7777/wwss/phoneService?wsdlweb
就能夠看到對應自動生成的WSDL文件:編程
This XML file does not appear to have any style information associated with it. The document tree is shown below. <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.ws.flying.at/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="PhoneServiceService" targetNamespace="http://service.ws.flying.at/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.ws.flying.at/" elementFormDefault="unqualified" targetNamespace="http://service.ws.flying.at/" version="1.0"> <xs:element name="getPhoneInfo" type="tns:getPhoneInfo"/> <xs:element name="getPhoneInfoResponse" type="tns:getPhoneInfoResponse"/> <xs:complexType name="getPhoneInfo"> <xs:sequence> <xs:element minOccurs="0" name="arg0" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="getPhoneInfoResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="tns:phone"/> </xs:sequence> </xs:complexType> <xs:complexType name="phone"> <xs:sequence> <xs:element minOccurs="0" name="name" type="xs:string"/> <xs:element minOccurs="0" name="produce" type="xs:string"/> <xs:element minOccurs="0" name="time" type="xs:dateTime"/> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="getPhoneInfoResponse"> <wsdl:part element="tns:getPhoneInfoResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="getPhoneInfo"> <wsdl:part element="tns:getPhoneInfo" name="parameters"></wsdl:part> </wsdl:message> <wsdl:portType name="PhoneService"> <wsdl:operation name="getPhoneInfo"> <wsdl:input message="tns:getPhoneInfo" name="getPhoneInfo"></wsdl:input> <wsdl:output message="tns:getPhoneInfoResponse" name="getPhoneInfoResponse"></wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="PhoneServiceServiceSoapBinding" type="tns:PhoneService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getPhoneInfo"> <soap:operation soapAction="" style="document"/> <wsdl:input name="getPhoneInfo"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="getPhoneInfoResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="PhoneServiceService"> <wsdl:port binding="tns:PhoneServiceServiceSoapBinding" name="PhoneServicePort"> <soap:address location="http://127.0.0.1:7777/wwss/phoneService"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
咱們平時使用別人發佈的WebService服務時,就須要閱讀相應的WSDL文件。瀏覽器
而後打開cmd命令行窗口:服務器
輸入wsimport -version命令並回車,看到以下輸出代表你JDK的webservice工具正常。數據結構
咱們輸入如下命令,根據wsdl文件自動生成class文件:併發
wsimport http://127.0.0.1:7777/wwss/phoneService?wsdl -d F:\ws -p at.ws.phoneapp
若是要生成原文件,即.java文件,可加入 -s 參數.編程語言
這時在F盤的ws目錄下能夠看一下生成的文件。
wsimport各類命令的用法和解釋,使用wsimport -help查詢。
而後使用以下命令把生成的.class和.java文件打成jar包,放到工程jar包依賴目錄下。
關於將代碼打成Jar包可參見該篇博客:http://my.oschina.net/u/2608182/blog/724756
如下是測試代碼:
@Test public void testws1() { PhoneServiceService phoneService = new PhoneServiceService(); PhoneService phoneService1 = phoneService.getPhoneServicePort(); //獲取到生成的本地Phone類,就能夠調用其中的任何對外開放的方法 Phone phone = phoneService1.getPhoneInfo("eeeeapple"); System.out.println(phone.getName()); System.out.println(phone.getProduce()); System.out.println(phone.getTime()); }
注意:以上的PhoneServiceService,PhoneService,Phone類均爲是經過WSDL文件自動生成的類,在import的時候不要引錯。
如下是輸出結果:
Tips:
1. 在類上添加@WebService註解,表明發佈一個WebService服務
2. 經過EndPoint(端點服務)發佈一個webService。Endpoint也是jdk提供的一個專門用於發佈服務的類,它的publish方法接收兩個參數,一個是本地的服務地址,二是提供服務的類。它位於javax.xml.ws.*包中。
3. Endpoint.publish(String address, Object implementor) 靜態方法在給定地址處針對指定的實現者對象建立併發布端點
4. 給類添加上@WebService註解後,類中全部的非靜態方法都將會對外公佈
5. 若是但願某個方法不對外公開,能夠在方法上添加@WebMethod(exclude=true),阻止對外公開。
6. 若是一個類上,被添加了@WebService註解,則必須此類至少有一個能夠公開的方法,不然將會啓動失敗。
7. protected、private、final、static方法不能對外公開 代碼以下:
@WebService // 添加了此註解,表明是一個WebService public class HelloWorld { // 非 static final private 方法默認會發布 public String sayHi(String name) { return "hello" + name; } @WebMethod(exclude=true) public void exclude(){ // 被註解排除的方法 } protected void protected1(){ //受保護的方法默認不發佈 } private void private1(){ // 私有方法默認不發佈 } public static void static1(){ // static 方法默認不發佈 } public final void final1(){ // final 方法默認不發佈 } }
元素 |
定義 |
<portType> |
web service 執行的操做 |
<message> |
web service 使用的消息 |
<types> |
web service 使用的數據類型 |
<binding> |
web service 使用的通訊協議 |
<definitions> <types> definition of types........ </types> <message> definition of a message.... </message> <portType> definition of a port....... </portType> <binding> definition of a binding.... </binding> </definitions> |
定義一個功能,在Java中叫作方法,在C中叫作函數;在Java中叫類,在C語言中叫作結構體。這些名詞都不同。
WSDL規範爲了避免會產生歧義,就定義了一些新的名詞來表述功能與服務。
<portType> 元素是最重要的 WSDL 元素。 它可描述一個 web service、可被執行的操做,以及相關的消息。 能夠把 <portType> 元素比做傳統編程語言中的一個函數庫(或一個模塊、或一個類)。
<operation>子元素:
對服務中所支持的操做的抽象描述,通常單個Operation描述了一個訪問入口的請求/響應消息對。
<message> 元素定義一個操做的數據元素。 每一個消息均由一個或多個部件組成。能夠把這些部件比做傳統編程語言中一個函數調用的參數。
通訊消息的數據結構的抽象類型化定義。使用Types所定義的類型來定義整個消息的數據結構。
<types> 元素定義 web service 使用的數據類型。 爲了最大程度的平臺中立性,WSDL 使用 XML Schema 語法來定義數據類型。
<binding> 元素爲每一個端口定義消息格式和協議細節。
這是某個 WSDL 文檔的簡化的片斷:
<message name="getTermRequest"> <part name="term" type="xs:string"/> </message>
<message name="getTermResponse"> <part name="value" type="xs:string"/> </message>
<portType name="glossaryTerms"> <operation name="getTerm"> <input message="getTermRequest"/> <output message="getTermResponse"/> </operation> </portType> |
在這個例子中,<portType> 元素把 "glossaryTerms" 定義爲某個端口的名稱,把 "getTerm" 定義爲某個操做的名稱。
操做 "getTerm" 擁有一個名爲 "getTermRequest" 的輸入消息,以及一個名爲 "getTermResponse" 的輸出消息。
<message> 元素可定義每一個消息的部件,以及相關聯的數據類型。
對比傳統的編程,glossaryTerms 是一個函數庫,而 "getTerm" 是帶有輸入參數 "getTermRequest" 和返回參數 getTermResponse 的一個函數。
Types、Message、PortType、Opration爲抽象定義。
Binding、Port、Service是實現。
Port:
定義爲協議/數據格式綁定與具體web訪問地址組合的單個服務訪問點。
Service:
相關服務訪問點的集合。
WSDL文件的內容,通常由服務默認生成,但爲了更好的向開發人員提供使用說明書,通常應作一些簡單的修改。至少不該該暴露咱們的包結構。而targetNamespace默認狀況下爲倒置的包名,這已經暴露了咱們的包結構。經過在類文件上添加如下註解,能夠修改wsdl生成的各元素,而不是直接去修改wsdl文件,直接去修改wsdl文件是無效的。
WebService的註解包括:
1. @WebService-定義服務 --類上
2. @WebMethod-定義方法 - 方法
3. @WebResult-定義返回值 – 返回值
4. @WebParam-定義參數 – 參數
1. 經過WebService的註解,能夠更加形像的描述Web服務。從而生成WSDL文檔。
2. 當修改了WebService註解以後,同時會影響客戶端生成的代碼。
3. 調用的方法名和參數名也發生了變化。
4. 即便是沒有修改源代碼,只修改了註解,客戶端的代碼也必需要從新生成(注意是生成而不是下載)。不然調用將會失敗。
5. 生成本地調用代碼,依然使用wsimport工具
1. @WebService 標註要暴露爲Web Services的類或接口 ,用於修飾類或接口,包含的屬性有:
2. targetNamespace屬性:定義命名空間,默認爲」http://」+」包名倒排」
3. name屬性:Web Service 的名稱,默認爲發佈服務的類名。
4. serviceName: ws服務的名詞,默認在類名後面添加了service
5. endpointInterface屬性:定義服務抽象 Web Service 協定的服務端點接口的完整名稱,接口也必須聲明WebService註解,包括方法的註解必須也要添加到接口中,不然會無效, 並且WS在沒有註解的狀況下.生成WS的時候會自動生成一個註解.因此能夠不用指定接口
1. 此註解用在方法上,用於修改對外暴露的方法
2. operationName屬性:與此方法匹配的 wsdl:operation 的名稱
3. exclude屬性:標註此方法是否被暴露,默認爲false
注意:若是全部方法上都沒有指定@WebMethod,則默認是全部的方法都是對外暴露的方法。若是有任一方法指定了@WebMethod,則只有指定這個註解的纔是對外暴露的方法。
@WebResult 定義返回值,返回值類型不能爲接口類或抽象類,並且必須有個不帶參的構造函數,包含屬性
name屬性:返回值的名稱
一個添加註解的案例:
// 修改web服務的名稱,和命名空間 @WebService(name="Hello",targetNamespace="http://icast.cn") public class HelloWorld { @WebMethod(operationName="aaa") // 修改webResult 和 webParam會影響到JS的調用模式 public @WebResult(name="returnName") String sayHi(@WebParam(name="yourname") String name){ return "Hello" + name; } public static void main(String[] args){ // 發佈一個web服務,指定IP和實現者 Endpoint end=Endpoint.publish("http://127.0.0.1:4567/hello",new HelloWorld()); } }