使用JDK自帶的WebService工具發佈WebService服務

1.建立簡單的WebService服務

首先咱們來建立一個用於對外發布的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 方法默認不發佈
	}
}

2.WSDL文件簡介

WSDL 文檔的組成部分:

元素

定義

<portType>

web service 執行的操做

<message>

web service 使用的消息

<types>

web service 使用的數據類型

<binding>

web service 使用的通訊協議

 

WSDL 文檔的主要結構:

<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>

 

WSDL元素介紹

    定義一個功能,在Java中叫作方法,在C中叫作函數;在Java中叫類,在C語言中叫作結構體。這些名詞都不同。

    WSDL規範爲了避免會產生歧義,就定義了一些新的名詞來表述功能與服務。

<portType>(WSDL端口)

<portType> 元素是最重要的 WSDL 元素。 它可描述一個 web service、可被執行的操做,以及相關的消息。 能夠把 <portType> 元素比做傳統編程語言中的一個函數庫(或一個模塊、或一個類)。

<operation>子元素:

對服務中所支持的操做的抽象描述,通常單個Operation描述了一個訪問入口的請求/響應消息對。

<message> (WSDL消息)

<message> 元素定義一個操做的數據元素。 每一個消息均由一個或多個部件組成。能夠把這些部件比做傳統編程語言中一個函數調用的參數。

通訊消息的數據結構的抽象類型化定義。使用Types所定義的類型來定義整個消息的數據結構。

<types>(WSDL types)

<types> 元素定義 web service 使用的數據類型。 爲了最大程度的平臺中立性,WSDL 使用 XML Schema 語法來定義數據類型。

 

<binding> (WSDL Bindings)

<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:

相關服務訪問點的集合。

3.使用WebService註解來修改WSDL文件

WSDL文件的內容,通常由服務默認生成,但爲了更好的向開發人員提供使用說明書,通常應作一些簡單的修改。至少不該該暴露咱們的包結構。而targetNamespace默認狀況下爲倒置的包名,這已經暴露了咱們的包結構。經過在類文件上添加如下註解,能夠修改wsdl生成的各元素,而不是直接去修改wsdl文件,直接去修改wsdl文件是無效的。

WebService的註解包括:

1.         @WebService-定義服務   --類上

2.         @WebMethod-定義方法   - 方法

3.         @WebResult-定義返回值 – 返回值

4.         @WebParam-定義參數 – 參數

 

WebService註解的使用

1.         經過WebService的註解,能夠更加形像的描述Web服務。從而生成WSDL文檔。

2.         當修改了WebService註解以後,同時會影響客戶端生成的代碼。

3.         調用的方法名和參數名也發生了變化。

4.         即便是沒有修改源代碼,只修改了註解,客戶端的代碼也必需要從新生成(注意是生成而不是下載)。不然調用將會失敗。

5.         生成本地調用代碼,依然使用wsimport工具

 

@WebService註解:

1.   @WebService 標註要暴露爲Web Services的類或接口 ,用於修飾類或接口,包含的屬性有:

2.   targetNamespace屬性:定義命名空間,默認爲」http://」+」包名倒排」

3.   name屬性:Web Service 的名稱,默認爲發佈服務的類名。

4.   serviceName: ws服務的名詞,默認在類名後面添加了service

5.   endpointInterface屬性:定義服務抽象 Web Service 協定的服務端點接口的完整名稱,接口也必須聲明WebService註解,包括方法的註解必須也要添加到接口中,不然會無效, 並且WS在沒有註解的狀況下.生成WS的時候會自動生成一個註解.因此能夠不用指定接口

 

@WebMethod

1.         此註解用在方法上,用於修改對外暴露的方法

2.   operationName屬性:與此方法匹配的 wsdl:operation 的名稱

3.   exclude屬性:標註此方法是否被暴露,默認爲false

 

注意:若是全部方法上都沒有指定@WebMethod,則默認是全部的方法都是對外暴露的方法。若是有任一方法指定了@WebMethod,則只有指定這個註解的纔是對外暴露的方法。

 

@WebResult

@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());
	}
}
相關文章
相關標籤/搜索