公司做的系統之間的交互用到了webservice做交互,現在對webservice做一個總結。
1.配置已有的webservice
webservice主要包括
- xml/json:作為傳輸數據的格式
- soap:(simple object access protocol)對於http做的封裝,是webservice用的服務協議。也有一種說法是:http+xml+soap = webservice
- wsdl:webservice define language:這是webservice的規范文件。
一般webservice的訪問包括四種格式:
- http-get
- http-post
- soap-get
- soap-post
java對webservice的支持沒有.net做的那么好,只能支持其中一種(soap-post),下面就用http-get使用HttpURLConnection做的webservice的調用
首先登陸http://www.webxml.com.cn/zh_cn/index.aspx右邊有個最新webservice
這里用中文<>英文雙向翻譯web服務作為例子,打開頁面點擊其中的服務說明,如圖所示(不好意思,qq截圖不知道怎么的打不了中文,我就用簡單的英文代替了)
打開:是關於這個webservice的WSDL文件,這個文件我們等下再去分析,我們此時只需要拖到最下面,找到http-get 所需要用的URL,最下面應該會有四種訪問方式的URL,我們只需要http-get的就可以了。
url應該是:http://fy.webxml.com.cn/webservices/EnglishChinese.asmx,然后我們回到上一個頁面,選擇:TranslatorSentenceString
這里不選上一個是因為java對webservice沒有.net支持的那么好,沒法用dataset去接,如圖所示:
打開之后,發現需要輸入參數wordkey:
我們可以開始寫代碼了,用HttpURLConnection寫一個調用http-get方法的訪問類。
package com.mz.webservice.b; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class TransLatorService { public void translate(String keyWord) { //我們要調用的webservice的url地址,我們用拼接字符串的形式用?wordKey=xxx來進行拼接 String httpUrl = "http://fy.webxml.com.cn/webservices/EnglishChinese.asmx/Translator?wordKey="+keyWord; try { URL url = new URL(httpUrl); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //設置訪問時間 conn.setConnectTimeout(5000); //訪問方式為get conn.setRequestMethod("GET"); //如果連接成功,則把返回的數據讀入buffer中 if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream is = conn.getInputStream(); ByteArrayOutputStream boas = new ByteArrayOutputStream(); byte[] buffer = new byte[10240]; int len = -1; while((len = is.read(buffer)) != -1) { boas.write(buffer, 0, len); } System.out.println("the output is:" + boas.toString("UTF-8")); boas.close(); is.close(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { TransLatorService ts = new TransLatorService(); ts.translate("death"); } }
返回值應該是一個關於單詞“death”的xml
the output is:<?xml version="1.0" encoding="utf-8"?> <DataSet xmlns="http://WebXml.com.cn/"> <xs:schema id="Dictionary" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="Dictionary" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Trans"> <xs:complexType> <xs:sequence> <xs:element name="WordKey" type="xs:string" minOccurs="0" /> <xs:element name="Pron" type="xs:string" minOccurs="0" /> <xs:element name="Info" type="xs:string" minOccurs="0" /> <xs:element name="Translation" type="xs:string" minOccurs="0" /> <xs:element name="Mp3" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Refer"> <xs:complexType> <xs:sequence> <xs:element name="Rel" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Sentence"> <xs:complexType> <xs:sequence> <xs:element name="Orig" type="xs:string" minOccurs="0" /> <xs:element name="Trans" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <Dictionary xmlns=""> <Trans diffgr:id="Trans1" msdata:rowOrder="0"> <WordKey>death</WordKey> <Pron>deθ</Pron> <Info /> <Translation>n. 死,死亡;死神</Translation> <Mp3>1694.mp3</Mp3> </Trans> <Sentence diffgr:id="Sentence1" msdata:rowOrder="0"> <Orig>That motorbike will be the death of you.</Orig> <Trans>那輛摩托車就會要了你的命。</Trans> </Sentence> <Sentence diffgr:id="Sentence2" msdata:rowOrder="1"> <Orig>That defeat meant the death of all my hopes.</Orig> <Trans>那次失敗毀滅了我所有的希望。</Trans> </Sentence> <Sentence diffgr:id="Sentence3" msdata:rowOrder="2"> <Orig>Car accident caused many deaths.</Orig> <Trans>車禍造成很多人死亡。</Trans> </Sentence> </Dictionary> </diffgr:diffgram> </DataSet>
我們剩下需要做的就是對這個xml進行解析,自己封裝一個解析類和方法,這樣做是很費時費力的,所以java提供了一套自己的機制。
我們可以直接封裝成實體類,直接調用方法,傳遞實體類返回實體類的方法來進行調用。
通過wsimport 命令進行生成相應的webservice的實體類。(提醒:必須配置java的環境變量,請自行上網參考,如果不會配置,並且需要jdk1.6_21的版本以上,否則會報錯!並且,請保持項目中的jre和控制台版本的一致性!)
語法 wsimport [opations] <wsdl_uri>
- wsdl_uri:wsdl 的統一資源標識符
- d :指定要輸出的文件的位置
- s :表示要解析java的源碼 ,默認解析出的是class字節碼
- p : 指定輸出的包名
好比我們如果要把剛剛的webservice服務進行相應的實體類的轉換,就是:
wsimport http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?WSDL
這里只會生成字節碼文件,沒有.java文件,並且字節碼文件會出現在你控制台目前的路徑下,所以這里先cd到了桌面,如圖所示:
這里報錯了,說明不能把相應的WSDL轉為我們需要的代理類,那么我們就可以把相應的網頁的xml報錯到本地,命名隨意,我就命名的a.xml(因為其實命令是解析一個wsdl文件,那么不管是解析網頁的還是本地的其實是一樣的)
找到相應的錯誤的地方(line 19 line 105)如圖所示
既然沒有辦法解析,那么就把這一行刪除掉,然后重新解析,命令如下:
cd Desktop(先轉移到桌面,因為xml文件是報錯在桌面的)
wsimport a.xml
warning是對其他幾種方式的不能解析,所以沒有error就算是解析成功了,如圖所示:
如果需要相應的指定,需要:
wsimport -s ./ -p com.hp.webservice.getTranslatorInfo a.xml
這里的-s是指的要生成的源碼地址,-p是包名,如下圖所示:
這個時候就可以新建一個項目,然后把上面生成的java文件拷到src目錄下(此處不截圖了,因為我們要分析一個最重要的東西,就是WSDL文件)
首先必須說明WSDL文件是從下往上看的:
往回找,如圖所示:
接着往上找:
接着向上找
最后找到參數類型:
tips:我知道有人會說那上面有的地方有中文解釋為什么還要找,我只想說很多時候很多公司內部的WSDL文件沒那么友好,至少我們公司就沒有!所以還是一步一步的
找上去吧,還有一個是最后的返回類型是TranlatorResult,有人說找不到,這個是定義在別的xml文件里的,就不去找了,反正知道返回的是一個List就可以了,下一篇我們自己來創建webservice項目會再說明的
綜上的WSDL文檔所述:
- 這個webservice的service name:EnglishChinese
- 我們所用的soap:EnglishChineseSoap
- 調用方法名:TranslatorString
- 輸入類型:String
- 輸出類型:TransLatorResult(在生成的代理文件里是AraayOfString)
好了,下面我們寫一個測試類:
package com.hp.webservice.getTranslatorInfo.test; import java.util.List; import com.hp.webservice.getTranslatorInfo.ArrayOfString; import com.hp.webservice.getTranslatorInfo.EnglishChinese; import com.hp.webservice.getTranslatorInfo.EnglishChineseSoap; public class GetTranslatorTest { public static void main(String[] args) { //首先先獲得一個服務 EnglishChinese eng = new EnglishChinese(); //通過服務獲取其中一種的soap方式 EnglishChineseSoap soap = eng.getEnglishChineseSoap(); //調用translatorString方法,並且傳遞一個英文單詞作為參數 ArrayOfString arrays = soap.translatorString("death"); //返回是一個webservice自定義的類型,我們需要通過getString方法獲得List List<String> infos = arrays.getString(); //通過xml文檔分析,list中的第四個元素是單詞釋義,輸出單詞釋義 System.out.println(infos.get(3)); } }
輸出結果應該是:
n. 死,死亡;死神
好了,到這里我們基本可以去使用別人的webservice了,自己建一個webservice項目下次再講