概念:java
一、WebService,顧名思義就是基於Web的服務。它使用Web(HTTP)方式,接收和響應外部系統的某種請求。從而實現遠程調用. web
二、咱們能夠調用互聯網上查詢天氣信息Web服務,而後將它嵌入到咱們的程序(C/S或B/S程序)當中來,當用戶從咱們的網點看到天氣信息時,他會認爲咱們爲他提供了不少的信息服務,但其實咱們什麼也沒有作,只是簡單調用了一下服務器上的一段代碼而已。ajax
三、學習WebService能夠將你的服務(一段代碼)發佈到互聯網上讓別人去調用,也能夠調用別人機器上發佈的WebService,就像使用本身的代碼同樣.。編程
簡單名詞:
服務器
名詞1:XML. Extensible Markup Language -擴展性標記語言併發
XML,用於傳輸格式化的數據,是Web服務的基礎。app
namespace-命名空間。工具
xmlns=「http://itcast.cn」 使用默認命名空間。post
xmlns:itcast=「http://itcast.cn」使用指定名稱的命名空間。學習
名詞2:WSDL – WebService Description Language – Web服務描述語言。
經過XML形式說明服務在什麼地方-地址。
經過XML形式說明服務提供什麼樣的方法 – 如何調用。
名詞3:SOAP-Simple Object Access Protocol(簡單對象訪問協議)
SOAP做爲一個基於XML語言的協議用於有網上傳輸數據。
SOAP = 在HTTP的基礎上+XML數據。
SOAP是基於HTTP的。
SOAP的組成以下:
Envelope – 必須的部分。以XML的根元素出現。
Headers – 可選的。
Body – 必須的。在body部分,包含要執行的服務器的方法。和發送到服務器的數據。
WSDL-說明服務在哪裏,如何調用,其實就是一個使用說明書:
SOAP協議的範本:-請求示例
如下發出HTTP請求,但不一樣的是向服務器發送的是XML數據!
SOAP協議:-響應示例:
響應的信息,同發送信息同樣,先必須是HTTP協議,而後再遵循SOAP協議
在Java項目中發佈第一個WS服務
一、用Jdk1.6.0_21之後的版本發佈一個WebService服務.
二、與Web服務相關的類,都位於javax.jws.*包中。
主要類有:
一、 @WebService - 它是一個註解,用在類上指定將此類發佈成一個ws.
二、 Endpoint – 此類爲端點服務類,它的方法publish用於將一個已經添加了@WebService註解對象綁定到一個地址的端口上。
@WebService(name = "WebApp", targetNamespace = "http://baobaodaren/") public class WebApp { public String sayHi(String name){ System.out.println("server go..."); return "youname"+name; } public static void main(String[] args) { Endpoint.publish("http://192.168.1.24:1234/hi", new WebApp()); System.out.println("server ready..."); } }
注意事項:
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註解,則必須此類至少有一個能夠公開的方法,不然將會啓動失敗。
服務發佈成功了,如何調用呢?請看說明書-WSDL:
在地址欄輸入(注意後面的參數?wsdl)
http://192.168.1.24:1234/hi?wsdl
目前不是訪問webService,只是獲取一個用於描述WebService的說明文件,即:wsdl文件.
wsdl- WebService Description Language,是以XML文件形式來描述WebService的」說明書」,有了說明書,咱們才能夠知道如何使用或是調用這個服務.
使用wsimport生成本地調用代碼:
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到咱們的項目中運行。
看懂使用說明書WSDL:
WebService經過HTTP協議完成遠程調用: (深刻分析) – RPC
WebService只採用HTTP POST方式傳輸數據,不使用GET方式; -- 握手,WSDL-get,
普通http post的contentType爲
application/x-www-form-urlencoded
WebService的contentType爲-即在Http的基礎上發SOAP協議
text/xml 這是基於soap1.1協議。
application/soap+xml 這是基於soap1.2協議。
WebService從數據傳輸格式上做了限定。WebService所使用的數據均是基於XML格式的。目前標準的WebService在數據格式上主要採用SOAP協議。SOAP協議實際上就是一種基於XML編碼規範的文本協議。
SOAP – Simple Object Access protocol 簡單對像訪問協議。是運行在HTTP協議基礎之上的協議。其實就是在HTTP協議是傳輸XML文件,就變成了SOAP協議。
SOAP1.1和SOAP1.2的 namespace不同。能夠經過查看類
javax.xml.ws.soap.SOAPBinding來查看裏面的常量
默認狀況下,Jdk1.6只支持soap1.1
即:@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING)
WebService和Web服務器的區別
WebService和Web服務器有什麼區別呢?咱們能夠把WebService看做是Web服務器上應用;反過來講,Web服務器是WebService運行時所必需的容器。這就是它們的區別和聯繫。
使用JDK1.6發佈的簡單Web服務,其內部實際上是使用Socket實現。能夠查看:SUN公司未對外公佈的API類com.sun.xml.internal.ws.transport.http.server. ServerMgr獲知,請使用反編譯工具。
WebService的特色:
WebService經過HTTP POST方式接受客戶的請求
WebService與客戶端之間通常使用SOAP協議傳輸XML數據.
它自己就是爲了跨平臺或跨語言而設計的。
客戶端調用WebService的方式:
經過wsimport生成客戶端代碼
經過客戶端編程的方式調用
經過ajax調用 (js+XML)
經過URLConnection調用
使用原生的ajax調用web服務:
因爲使用ajax – js調用web服務完成不一樣於使用java代碼調用。因此,必需要對SOAP文件很是的瞭解。
通常使用ajax調用,應該是在已經獲知瞭如下信息之後纔去調用:
獲知請求(request)的soap文本。
獲知響應(response)的soap文本。
客戶端經過編程的方式訪問服務:
使用javax.xml.ws.Service類用於訪問web服務。
關鍵類Service:
方法create – 用戶建立Service對像,提供wsdlurl和服務名。
getPort-用於經過指定namespace,portName和接口的範型。
在客戶端須要一個與服務器接口徹底相同的類。(仍然使用工具生成。但只須要一個接口。並須要簡單修改。若是返 回的是複雜數據類型如POJO,還須要將POJO一併放到項目中)-不要試圖經過-p來修改包名,會出錯的。
關鍵類QName – 被稱爲徹底限定名即:Qualified Name的縮寫:
QName 的值包含名稱空間 URI、本地部分和前綴
經過URLConnection調用:
/** * 經過URLConnection調用webService服務 * @author Administrator * */ public class URLConnectionApp { public static void main(String[] args) throws Exception { //制定websercice的地址 String wsUrl = "http://192.168.1.24:1234/hi"; URL url = new URL(wsUrl); URLConnection coon = url.openConnection(); HttpURLConnection con = (HttpURLConnection)coon; //設置請求方式 con.setDoInput(true); con.setDoOutput(true); con.setRequestMethod("POST"); con.setRequestProperty("content-type","text/xml;charset=UTF-8"); //手動構造請求體 String requestBoby="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "+ " xmlns:q0=\"http://webxml.com.cn/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema \" "+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+ "<soapenv:Body><q0:sayHi><arg0>lisi</arg0> <arg1>10</arg1> </q0:sayHi></soapenv:Body></soapenv:Envelope>"; OutputStream out = con.getOutputStream(); out.write(requestBoby.getBytes()); out.close(); int code = con.getResponseCode(); if(code==200){ InputStream input = con.getInputStream(); byte[] b = new byte[1024]; StringBuffer sb = new StringBuffer(); int len = 0; while((len=input.read(b))!=-1){ String str = new String(b,0,len,"UTF-8"); sb.append(str); } System.out.println(sb.toString()); input.close(); } con.disconnect(); } }
經過wsimport生成客戶端代碼:
以上就是簡單的webservice