WebService就是這麼簡單
WebService介紹
首先我們來談一下為什麼需要學習webService這樣的一個技術吧….
問題一
如果我們的網站需要提供一個天氣預報這樣一個需求的話,那我們該怎麼做?????
天氣預報這麼一個功能並不是簡單的JS組件就能夠實現的,它的數據是依賴資料庫分析出來的,甚至需要衛星探測..我們個人建站是不可能搞這麼一個資料庫的吧。
那麼既然我們自己幹不了,我們可以去找別人嗎???我們從搜索引擎搜索,可以發現很多提供天氣預報的網站,但是它返回的是一個網頁,而我們僅僅需要的是對應的數據!
我們可能就在想,我們能不能僅僅只要它返回的數據,而並不是經過加工處理後返回的網頁呢??
於是乎,webService就誕生了,webservice就是一個部署在Web伺服器上的,它向外界暴露出一個能夠通過Web進行調用的API。也就是說:當我們想要獲取天氣預報的信息,我們可以調用別人寫好的service服務,我們調用就能夠得到結果了!
問題二
可是我們寫網站主流的就有好幾個平台:Java、.net、PHP等等,那麼部署在Web伺服器上的伺服器也就是webserice怎麼能夠就讓我們不同的平台都能夠調用呢??
我們知道java、.net這樣的平台他們語言的基本數據類型、複雜數據類型就可能不一樣,那麼怎麼能夠實現調用的呢???
來引用一段話
大家在寫應用程序查詢資料庫時,並沒有考慮過為什麼可以將查詢結果返回給上層的應用程序,甚至認為,這就是資料庫應該做的,其實不然,這是資料庫通過TCP/IP協議與另一個應用程序進行交流的結果,而上層是什麼樣的應用程序,是用什麼語言,資料庫本身並不知道,它只知道接收到了一份協議,這就是SQL92查詢標準協議。
無論是Java、.net、PHP等等的平台,只要是網頁開發都是可以通過http協議來進行通信的,並且返回的數據要是通用的話,那麼我們早就學過這樣的一種技術【XML】
所以webservice實際上就是http+XML
這裡寫圖片描述
對webservice的理解
WebService,顧名思義就是基於Web的服務。它使用Web(HTTP)方式,接收和響應外部系統的某種請求。從而實現遠程調用.
我們可以調用互聯網上查詢天氣信息Web服務,然後將它嵌入到我們的程序(C/S或B/S程序)當中來,當用戶從我們的網點看到天氣信息時,他會認為我們為他提供了很多的信息服務,但其實我們什麼也沒有做,只是簡單調用了一下伺服器上的一段代碼而已。
學習WebService可以將你的服務(一段代碼)發布到互聯網上讓別人去調用,也可以調用別人機器上發布的WebService,就像使用自己的代碼一樣.。
回顧Socket
我們在學習Java基礎網路編程章節已經知道了Scoket這麼一個連接了。
Socket服務端
Socket客服端
當我們從客戶端輸入數據以後,那麼服務端就會把數據轉成是大寫
這裡寫圖片描述這裡寫圖片描述
其實HTTP協議就是基於Socket對其進行封裝,我們也可以在IE瀏覽器中對其進行訪問.我們一樣能夠獲取得到數據!
這裡寫圖片描述這裡寫圖片描述
Scoket與HTTP簡述
這裡寫圖片描述
ISO的七層模型 : 物理層、數據鏈路層、網路層、傳輸層、表示層、會話層、應用層
Socket訪問 :Socket屬於傳輸層,它是對Tcp/ip協議的實現,包含TCP/UDP,它是所有通信協議的基礎,Http協議需要Socket支持,以Socket作為基礎
Socket通信特點:
開啟埠,該通信是 長連接的通信 ,很容易被防火牆攔截,可以通過心跳機制來實現 ,開發難度大
傳輸的數據一般是字元串 ,可讀性不強
socket埠不便於推廣
性能相對於其他的通信協議是最優的
Http協議訪問 :屬於應用層的協議,對Socket進行了封裝
跨平台
傳數據不夠友好
對第三方應用提供的服務,希望對外暴露服務介面
問題:
**數據封裝不夠友好 :可以用xml封裝數據 **
希望給第三方應用提供web方式的服務 (http + xml) = web Service
webService相關術語
名詞1:XML.Extensible Markup Language-擴展性標記語言
XML,用於傳輸格式化的數據,是Web服務的基礎。
namespace-命名空間。
xmlns=「//itcast.cn」 使用默認命名空間。
xmlns:itcast=「//itcast.cn」使用指定名稱的命名空間。
名詞2:WSDL –WebService Description Language– Web服務描述語言。
通過XML形式說明服務在什麼地方-地址。
通過XML形式說明服務提供什麼樣的方法 – 如何調用。
名詞3:SOAP-Simple Object Access Protocol(簡單對象訪問協議)
Envelope – 必須的部分。以XML的根元素出現。
Headers – 可選的。
Body – 必須的。在body部分,包含要執行的伺服器的方法。和發送到伺服器的數據。
SOAP作為一個基於XML語言的協議用於有網上傳輸數據。
SOAP = 在HTTP的基礎上+XML數據。
SOAP是基於HTTP的。
SOAP的組成如下:
快速入門
首先,我們來嘗試一下調用別人寫好的webService,來體驗一把:我們訪問http://www.webxml.com.cn/zh_cn/index.aspx
這裡寫圖片描述
進入到裡邊
這裡寫圖片描述
當我們輸入一個號碼,它就能夠查詢出我們的手機位置信息:
我們現在要做的就是將這個服務讓我們自己寫的應用程序中也可以調用,那怎麼做呢???
http-get方式訪問webservice
這裡寫圖片描述
這裡寫圖片描述
Http-Client 框架POST請求
為什麼要使用HttpClient工具:
原生態的Socket基於傳輸層,現在我們要訪問的WebService是基於HTTP的屬於應用層,所以我們的Socket通信要藉助HttpClient發HTTP請求,這樣格式才能匹配
HttpClient使用步驟如下:
創建 HttpClient 的實例
創建某種連接方法的實例,在這裡是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
配置要傳輸的參數,和消息頭信息
調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
通過response讀取字元串
釋放連接。無論執行方法是否成功,都必須釋放連接
wsimport
上面我們使用的是GET方式或者使用Http-Client框架來調用webservice的服務,其實這兩種方式也有弊端
傳遞參數麻煩【get方式都寫在請求地址上、post方式要一個一個封裝】
解析結果麻煩【根據返回的XML來解析字元串】
如果我們可以把整個對象傳遞進去,返回的結果更加友好的話,就好像我們平常調用Java類一樣使用webservice就好咯!
Java也提供了類似的方法,把webservice服務搞成是Java類讓我們自己調用,既然是Java類的話,那麼我們使用起來就非常方便了!
把webservice服務搞成是Java類讓我們自己調用其實就是Java幫我們生成本地代理,再通過本地代理來訪問webservice
快速入門
wsimport是Java自帶的一個命令,我們想要使用該命令,就必須配置環境變數,並且jdk的版本最好是1.7或以上
值得注意的是:ide帶的JDK版本要和wsimport生成本地的版本一致,不然就用不了!!!
wsimport使用:wsimport命令後面跟著的是WSDL的url路徑語法
wsdl_uri:wsdl 的統一資源標識符
d :指定要輸出的文件的位置
s :表示要解析java的源碼 ,默認解析出的是class位元組碼
p : 指定輸出的包名
這裡寫圖片描述
首先我們先把cmd的路徑退到桌面上:
這裡寫圖片描述
然後對WSDL文件生成本地代理
這裡寫圖片描述
這裡寫圖片描述
該本地代理其實就是一堆的位元組碼文件
這裡寫圖片描述
將得到的位元組碼文件打包成jar,那麼我們只要在項目中導入jar包,就可以調用了!
語法
這裡寫圖片描述
本來我是想將本地代理的class文件生成jar包,然後導入到idea環境下,那麼直接調用就行了。可是idea老是報出找不到對應的類,找了半天也找不到,很煩呀!!!!我考慮了以下的幾種情況
** 生成的class文件的JVM和idea下的JVM環境不匹配【後來切換了也不行】**
idea緩存原因,把idea所有緩存去掉也不行
生成的本地代理包名cn不行【???idea就是對cn這個包名報錯,後來我改成自定義的包名也不行】
最後我還是沒有找到辦法,如果知道是什麼原因的,麻煩在評論中告訴我吧….因此這次的測試import,我就不僅僅生成class位元組碼文件,還生成了.java文件。我就直接使用java文件來測試了。
在zhongfucheng目錄下生成本地代理,把java源碼也帶上
這裡寫圖片描述
於是我就把java源碼複製到我的項目中,用java源碼來進行測試
這裡寫圖片描述
解析WSDL
有的同學可能會疑問,為啥wsimport能那麼厲害,將這麼一個url生成本地代理,其實我們看了WSDL文件就知道了。
這裡寫圖片描述
值得注意的是,本地代理僅僅是有其方法,類,並不能解析出具體的實現的。具體的操作其實還是webservice去完成的。代理這麼一個概念就更加清晰了。
自定義webservice服務
我們在上一章節中已經使用wsimport生成本地代理來調用webservice的服務了,其實我們自己寫的web應用程序也是可以發布webservice的
我們發布了webservice的話,那麼其他人也是可以調用我們自己寫的webservice!
那麼我們怎麼自定義webservice然後發布出去呢???
在jdk 1.6 版本以後 ,**通過jax-ws 包提供對webservice的支持 **
該方式通過註解的方式來聲明webservice
通過 jdk EndPoint.publish()發布webserive服務
快速入門
寫一個實體:
發布service,通過註解來讓WSDL文件更加可讀…
在類上添加@WebService註解,代表發布一個WebService服務
通過EndPoint(端點服務)發布一個webService。Endpoint也是jdk提供的一個專門用於發布服務的類,它的publish方法接收兩個參數,一個是本地的服務地址,二是提供服務的類。它位於javax.xml.ws.*包中。
Endpoint.publish(String address, Object implementor) 靜態方法在給定地址處針對指定的實現者對象創建並發布端點
給類添加上@WebService註解後,類中所有的非靜態方法都將會對外公布
如果希望某個方法不對外公開,可以在方法上添加@WebMethod(exclude=true),阻止對外公開。
如果一個類上,被添加了@WebService註解,則必須此類至少有一個可以公開的方法,否則將會啟動失敗。
protected、private、final、static方法不能對外公開
這裡寫圖片描述
生成的webservice能夠在瀏覽器訪問
這裡寫圖片描述
SOAP協議
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述
目前WebService的協議主要有SOAP1.1和1.2。
兩者的命名空間不同。
xmlns:soap="http://www.w3.org/2003/05/soap-envelope「
xmlns:soap=「http://schemas.xmlsoap.org/soap/envelope/ 「
Soap1.1的命名空間:
Soap1.2 命名空間:
SOAP1.1版本與SOAP1.2版本在頭信息上存在差異。
SOAP1.1存在SOAPAction的請求頭。
SOAP1.2沒有SOAPAction的請求頭。
基於SOAP1.1生成的WSDL和基於SOAP1.2生成的WSDL也不一樣。
主要看命名空間。
在CXF中兩種協議請求的方式也不一樣。
1.1為content-Type:text/xm;charset=UTF-8
1.2為content-Type:application/soap+xml;charset=UTF-8
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
SOA、UDDI概念
SOA
Soa(Service-Oriented Architecture):面向服務的架構,它是一種思想,IBM大力倡導是即插即用的,IBM大力提倡,希望以組裝電腦的方式來開發應用
組成:
面向web的服務,面向web的組件 :WebService : 硬碟、cpu、內存條
企業服務匯流排 (EnterPrise Service Bus :ESB)。主板
uddi
uddi (Universal Description, Discovery and Integration)統一描述、發現、集成
它是目錄服務,通過該服務可以註冊和發布webservcie,以便第三方的調用者統一調用
用得並不太多。
實現介面的webservice
服務端
客戶端
CXF框架
Apache CXF 是一個開源的 Services 框架,CXF 幫助您來構建和開發 Services 這些 Services 可以支持多種協議,比如:SOAP、POST/HTTP、RESTful HTTP CXF 大大簡化了 Service可以天然地和 Spring 進行無縫集成。
CXF介紹 :soa的框架
* cxf 是 Celtrix (ESB框架)和 XFire(webserivice) 合併而成,並且捐給了apache
* CxF的核心是org.apache.cxf.Bus(匯流排),類似於Spring的 ApplicationContext
* CXF默認是依賴於Spring的
* Apache CXF 發行包中的jar,如果全部放到lib中,需要 JDK1.6 及以上,否則會報JAX-WS版本不一致的問題
* CXF 內置了Jetty伺服器 ,它是servlet容器,好比tomcat
CXF特點
與Spring、Servlet做了無縫對接,cxf框架裡面集成了Servlet容器Jetty
支持註解的方式來發布webservice
能夠顯示一個webservice的服務列表
能夠添加攔截器:輸入攔截器、輸出攔截器 :
輸入日誌信息攔截器、輸出日誌攔截器、用戶許可權認證的攔截器
CXF開發
要想使用CXF框架,那麼就先導入jar包
asm-3.3.jar
commons-logging-1.1.1.jar
cxf-2.4.2.jar
jetty-continuation-7.4.5.v20110725.jar
jetty-http-7.4.5.v20110725.jar
jetty-io-7.4.5.v20110725.jar
jetty-security-7.4.5.v20110725.jar
jetty-server-7.4.5.v20110725.jar
jetty-util-7.4.5.v20110725.jar
neethi-3.0.1.jar
wsdl4j-1.6.2.jar
xmlschema-core-2.0.jar
介面
實現:
CXF與Spring集成
?建立一個web項目
?準備所有jar包,將CXF_HOMElib項目下的所有jar包,全部都拷貝新項目的lib目錄下.其中裡面已經包含了Sring3.0的jar包 其中jetty 伺服器的包可以不要.因為我們要部署的tomcat伺服器中了
?在web.xml中配置cxf的核心servlet,CXFServlet
?此配置文件的作用類 攔截/ws/*的所有請求 類似Struts2的過濾器
web.xml配置文件:
實體:
介面:
介面實現:
Spring配置信息:
IDEA下使用webservice
我們的Intellij idea是一個非常好用的java ide,當然了,它也支持webservice開發。非常好用…由於在網上見到的教程非常多,我就貼幾個我認為比較好的教程:
http://www.biliyu.com/article/986.html
http://blog.csdn.net/dreamfly88/article/details/52350370
獲取天氣預報
我們現在webservice就基本入門了,現在我想要做的就是自己寫的網站能夠拿到天氣預報的信息,於是我去http://www.webxml.com.cn/zh_cn/index.aspx找到了天氣預報的服務
這個是天氣預報的WSDL地址:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx,那麼我們只要解析該WSDL服務即可
這裡寫圖片描述
如果不想得到所有的信息,那麼我們可以在服務上找到我們想要對應的數據,也就是說:
這裡寫圖片描述
這裡寫圖片描述
總結
應用webservice的原因就在於我們需要一些服務、這些服務是我們自己不能手動寫的。比如天氣預報,於是就出現了webService技術。webService能夠讓我們可以獲取網上別人發布出來的服務。我們只要調用它,就可以獲取相關的數據了。
Socket其實就是對TCP/IP協議的一個封裝,而我們在網上使用的是HTTP協議。WebService也是Web應用程序。它也當然支持HTTP協議了。不過WebService需要給不同語言都能夠使用,因此它使用XML來進行傳輸。
於是,它就有自己一種協議:SOAP(簡單對象訪問協議)。其實SOAP就是Http+XML。
我們可以使用http-get方式訪問webservice,由於它使用的是原生Socket來進行訪問。會有點複雜。於是我們可以藉助Http-Client 框架來訪問WebService。Http-Client 框架比HTTP-GET方式會簡單一點。但還是不夠簡潔。
最後,我們可以使用Java自帶的WsImport來實現本地代理。這種方法會將WebService翻譯成Java類,我們使用類一樣去訪問WebService就行了。非常好用。
我們是可以自己寫webService的。對服務類上加上註解。通過EndPoint(端點服務)就能夠把我們webService服務類發布出去了。
為了讓WDSL文件更加讀取,可以使用註解的方式來寫好對應的參數名稱。
也可以控制某方法是否被發布出去
SOAP其實上就是使用XML進行傳輸的HTTP協議。
SOA:面向服務架構。即插即用。也就是耦合非常低,用的時候加上就行了。
UDDI (Universal Description, Discovery and Integration)統一描述、發現、集成,其實就是一個webservice的目錄結構,不過我們很少把webservice發布到上面去
實現介面的webservice只是在類上對其的一種抽象而已,沒什麼大不了的。
CXF框架可以與spring無縫連接,就不用我們自己Endpoint了。它還能記錄日誌之類的。
我們還可以使用Idea下的webservice,能夠使用圖形畫面的方式獲取本地代理和生成WSDL文件。
※納稅服務系統二POI、用戶唯一性校驗
※納稅服務系統五配置系統、子系統首頁、登陸與攔截
TAG:Java3y |