WebService 學習筆記
一.如何發佈一個web服務:
1、在類上添加@WebService註解。
這是jdk1.6提供的一個註解。它位於:javax.jws.*包中。
2、通過EndPoint(端點服務)發佈一個webService。
Endpoint也是jdk提供的一個專門用於發佈服務的類,它的publish方法接收兩個參數,一個是本地的服務地址,二是提供服務的類。它位於javax.xml.ws.*包中。
static Endpoint.publish(String address, Object implementor)
在給定地址處針對指定的實現者對象創建併發布端點。
stop方法用於停止服務。
EndPoint發佈完成服務以後,將會獨立的線程運行。所以,publish之後的代碼,可以正常執行。
其他注意事項:
給類添加上@WebService註解後,類中所有的非靜態方法都將會對外公佈。
不支持靜態方法,final方法。-
如果希望某個方法(非static,非final)不對外公開,可以在方法上添加@WebMethod(exclude=true),阻止對外公開。
如果一個類上,被添加了@WebService註解,則必須此類至少有一個可以公開的方法,否則將會啓動失敗。
//1、添加註解
@WebService
public class OneService {
//2、至少包含一個可以對外公開的服務
public String sayHello(String name){
System.err.println("invoke "+name);
return "Hello "+name;
}
public static void main(String[] args) {
//3、第一個參數稱爲Binding即綁定地址,
//第二個參數是實現者,即誰提供服務
Endpoint.publish("http://localhost:9999/one", new OneService());
}
}
二 .服務發佈成功了,如何調用呢?請看說明書-WSDL:
在地址欄輸入(注意後面的參數?wsdl)
http://127.0.0.1:9999/helloworld?wsdl
目前不是訪問webService,只是獲取一個用於描述WebService的說明文件,即:wsdl文件.
wsdl- WebService Description Language,是以XML文件形式來描述WebService的”說明書”,有了說明書,我們纔可以知道如何使用或是調用這個服務.
- 使用wsimport生成本地調用代碼:
說明書看不懂怎麼辦?別急JDK能看懂:
wsimport是jdk自帶的,可以根據wsdl文檔生成客戶端調用代碼的工具.當然,無論服務器端的WebService是用什麼語言寫的,都將在客戶端生成Java代碼.服務器端用什麼寫的並不重要.
wsimport.exe位於JAVA_HOME\bin目錄下.
常用參數爲:
-d<目錄> - 將生成.class文件。默認參數。
-s<目錄> - 將生成.java文件。
-p<生成的新包名> -將生成的類,放於指定的包下。
(wsdlurl) - http://server:port/service?wsdl,必須的參數。
示例:
C:/> wsimport –s . http://192.168.0.100/one?wsdl
注意:-s不能分開,-s後面有個小點,用於指定源代碼生成的目錄。點即當前目錄。
如果使用了-s參數則會在目錄下生成兩份代碼,一份爲.class代碼。一份爲.java代碼。
.class代碼,可以經過打包以後使用。.java代碼可以直接Copy到我們的項目中運行。
三 客戶端調用WebService的方式
通過wsimport生成客戶端代碼
通過客戶端編程的方式調用
通過ajax調用 (js+XML)
通過URLConnection調用
1.使用原生的ajax調用web服務:
由於使用ajax – js調用web服務完成不同於使用java代碼調用。所以,必須要對SOAP文件非常的瞭解。
一般使用ajax調用,應該是在已經獲知了以下信息以後纔去調用:
獲知請求(request)的soap文本。
獲知響應(response)的soap文本。
我們可以通過WSExplorer獲取上面的文本
2 Ajax 調用獲取所有用戶:
2 客戶端通過編程的方式訪問服務:
使用javax.xml.ws.Service類用於訪問web服務。
關鍵類Service
方法create – 用戶創建Service對象,提供wsdlurl和服務名。
getPort-用於通過指定namespace,portName和接口的範型。
在客戶端需要一個與服務器接口完全相同的類。(仍然使用工具生成。但只需要一個接口。並需要簡單修改。如果返回的是複雜數據類型如POJO,還需要將POJO一併放到項目中) - 不要試圖通過-p來修改包名,會出錯的。
關鍵類QName – 被稱爲完全限定名即:Qualified Name的縮寫。
QName 的值包含名稱空間 URI、本地部分和前綴
五.使用WebServiceExplorer只可以看到SOAP的XML數據,並看不到HTTP協議的頭。
既然是用HTTP發XML數據,就一定會有HTTP頭,爲了獲取HTTP頭,我們使用TCP/IP Monitor.
使用TCP/IP Monitor-攔截HTTP請求頭和響應頭及Body部分:
此工具位於:window>show view>other>MyEclipse Common(常用工具)>TCP/IP Monitor
前面的WSExplorer只參獲取消息體部分。爲了獲取HTTP請求的具體信息,我們可以
使用monitor;
因爲SOAP是在HTTP的基礎上發XML數據,前面的XML數據已經可以獲取到了,那麼,既然是在HTTP上收發消息,就一定會有HTTP的頭信息,那HTTP頭信息又
是怎麼樣的呢?
六 SOAP請求過程分析:
第一步:使用get方式獲取wsdl文件,稱爲握手。對於JDK1.6生成的ws服務,由於內部有一兩個配置文件,所以會發出兩次get請求。其他的一般爲一次。
第二步:用戶發出請求將使用post方式。
第三步:服務器響應成功。
發出去的XML文本:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.itcast.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body> //SOAP協議必須擁有body元素
<q0:sayHello> //SOAP協議必須通過第一個節點指明需要調用的方法
<arg0>aaa</arg0>
</q0:sayHello>
</soapenv:Body>
</soapenv:Envelope>
攔截到的返回信息:
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:sayHiResponse xmlns:ns2="http://ws.itcast.cn/">
<return>HelloWorld</return>
</ns2:sayHiResponse>
</S:Body>
</S:Envelope>
深入分析說明書WSDL:
wsdl – WebService Description Language(WS描述語言)
它主要定義了三個方面的問題:
What?即服務是什麼?
(portType,types,message)
How?如何調用服務?
通過binding元素說明調用服務的方式:soap,soap12,post,get.
Where?在哪兒調用服務?
Service元素,soap:address.
七:修改wsdl文件的內容
WSDL文件的內容,一般由服務默認生成,但爲了更好的向開發人員提供使用說明書,一般應做一些簡單的修改。至少不應該暴露我們的包結構。而targetNamespace默認情況下爲倒置的包名,這已經暴露了我們的包結構。
通過在類文件上添加以下註解,可以修改wsdl生成的各元素,而不是直接去修改wsdl文件,直接去修改wsdl文件是無效的。
WebService的註解包括:
@WebService-定義服務 --類上
@WebMethod-定義方法 - 方法
@WebResult-定義返回值 – 返回值
@WebParam-定義參數 – 參數
八:註解的作用
通過WebService的註解,可以更加形像的描述Web服務。從而生成WSDL文檔。
當修改了WebService註解之後,同時會影響客戶端生成的代碼。調用的方法名和參數名也發生了變化。即使是沒有修改源代碼,只修改了註解,客戶端的代碼也必須要重新生成(注意是生成而不是下載)。否則調用將會失敗。生成本地調用代碼,依然使用wsimport工具。
@WebService註解:
@WebService註解,作用在具體類上。而不是接口。
一個類只有添加了此註解纔可以通過Endpoint發佈爲一個web服務。
一個添加了此註解的類,必須要至少包含一個實例方法。
靜態方法和final方法不能被髮布爲服務方法
WebService註解包含以下參數
@WebMethod
此註解用在方法上,用於修改對外暴露的方法。
@WebResult用於定製返回值到WSDL的映射:
@WebParam用於定義WSDL中的參數映射:
從wsdl中分析出類的關係: