WebService能夠使運行在不同機器上的不同應用無需借助附加的、專門的第三方軟件或引薦,就可相互交換數據或集成。依據WebService的規范實施的應用之間,無論它們所使用的語言、平台或內部協議是什么,都可以相互交換數據。
WebService就是一個部署在web服務器上的應用程序,它向外界暴露出一個能夠通過web進行調用的API。這就是說,能用編程的方法通過web來調用這個應用程序。我們把調用這個WebService的應用程序稱為客戶端,發布這個web服務的機器稱為WebService服務器。
架構趨勢(WebService架構):

現在項目可能存在多種類型的終端,例如ipad等終端可能只有頁面,需要遠程調用控制層或業務邏輯。
一、調用已發布的WebService服務
接下來就以查詢手機號碼歸屬地為例,看看程序是如何調用WebService服務。
在開始寫代碼之前,首先需要添加HttpClient依賴,HttpClient是一款測試工具,可以在java代碼中模擬HTTP請求協議。
maven依賴:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
登錄http://www.webxml.com.cn在最新web services中找到國內手機號碼歸屬地查詢WEB服務:

點擊進入如下頁面:

點擊getMobileCodeInfo可以看到有SOAP1.1、SOAP1.2、HTTP GET、HTTP POST四種請求方式,接下來先看看HTTP GET請求。
1.1 get請求

上面一段表示發送請求數據格式、下面一段表示返回的數據格式。
代碼清單:
/**
* 調用第三方ws服務,查詢手機號碼歸屬地
*
*/
public class PhoneClient {
public static void main(String[] args) throws IOException {
String number = "13888888888";
get(number);
}
public static void get(String number) throws IOException {
// 創建瀏覽器對象
HttpClient httpClient = new HttpClient();
String url = "http://ws.webxml.com.cn" +
"/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode="+ number +"&userID=";
// 填寫數據,發送請求
GetMethod getMethod = new GetMethod(url);
int code = httpClient.executeMethod(getMethod);
System.out.println("http狀態:" + code);
String result = getMethod.getResponseBodyAsString();
System.out.println("返回結果為:" + result);
}
}
【測試結果】:
http狀態:200
返回結果為:<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://WebXml.com.cn/">13888888888:雲南 昆明 雲南移動合家歡卡</string>
1.2 post請求

同樣地,上面的部分表示請求的數據格式和響應,下面的部分表示返回數據
代碼清單:
/**
* 調用第三方ws服務,查詢手機號碼歸屬地
*
*/
public class PhoneClient {
public static void main(String[] args) throws IOException {
String number = "13888888888";
post(number);
}
public static void post(String number) throws IOException {
// 創建瀏覽器對象
HttpClient httpClient = new HttpClient();
String url = "http://ws.webxml.com.cn" +
"/WebServices/MobileCodeWS.asmx/getMobileCodeInfo";
// 填寫數據,發送請求
PostMethod postMethod = new PostMethod(url);
postMethod.setParameter("mobileCode", number);
postMethod.setParameter("userID", "");
int code = httpClient.executeMethod(postMethod);
System.out.println("http狀態:" + code);
String result = postMethod.getResponseBodyAsString();
System.out.println("返回結果為:" + result);
}
}
【測試結果】:
http狀態:200
返回結果為:<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://WebXml.com.cn/">13888888888:雲南 昆明 雲南移動合家歡卡</string>
上面的兩種方式本質上依然是http請求。
1.3 soap方式調用WebService
soap即簡單對象訪問協議。

從上圖中發現用的依然是http post方法,但是請求的數據格式變成了XML,有利於數據的維護。
我們使用流的方式讀取請求的數據格式,在resources文件下添加soap.txt文件:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getMobileCodeInfo xmlns="http://WebXml.com.cn/">
<mobileCode>13888888888</mobileCode>
<userID></userID>
</getMobileCodeInfo>
</soap:Body>
</soap:Envelope>
代碼清單:
/**
* 調用第三方ws服務,查詢手機號碼歸屬地
*
*/
public class PhoneClient {
public static void main(String[] args) throws Exception {
soap();
}
public static void soap() throws IOException {
// 創建瀏覽器對象
HttpClient httpClient = new HttpClient();
String url = "http://ws.webxml.com.cn" +
"/WebServices/MobileCodeWS.asmx";
PostMethod postMethod = new PostMethod(url);
// 傳輸XML數據,通過流的方式加載xml數據
String filepath = "D:\\IDEASpace\\WebService-Sample\\MyClient\\src\\main\\resources\\soap.txt";
postMethod.setRequestBody(new FileInputStream(filepath));
int code = httpClient.executeMethod(postMethod);
System.out.println("http狀態:" + code);
String result = postMethod.getResponseBodyAsString();
System.out.println("返回結果為:" + result);
}
}
【測試結果】:

這是因為post請求格式默認為:
Content-Type: application/x-www-form-urlencoded
當使用soap是需要指定:
Content-Type: text/xml; charset=utf-8
那么,手動設置一下Content-Type的值,添加一行代碼:
postMethod.setRequestHeader("Content-Type", "text/xml;charset=utf-8");
二、使用wsimport生成客戶端代碼並調用ws服務
通過HttpClient工具模擬http請求在java bean調用ws服務獲取手機查詢功能。調用的方式:get/post/soap。本質上還是通過http方式調用,只是調用的時候可以傳輸XML數據。HttpClient是java調用http協議的解決方案,這就有了語言瓶頸,只能限於java語言。
WebService推薦的解決方案:wsimport命令
接下來,打開jdk的安裝目錄,在bin下可以看到這樣一個命令:

這個就是java的ws解決方案。
首先,在號碼歸屬地頁面找到服務說明。點擊進入獲取的它網址:
http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL
1.命令:
wsimport http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL
解析WSDL(WS描述語言),解析完成后生成Java Bean

2.命令:
wsimport -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL
解析完成后生成class和java源文件

3.命令:
wsimport -s . -p com.xxyh.webservice http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL
解析完成后生成class和java源文件,及自定義包結構:

接着,將java源文件添加進項目:

我們在com.xxyh.webservice包下創建一個PhotoMain類:
public class PhoneMain {
public static void main(String[] args) {
// 獲取一個ws服務
MobileCodeWS ws = new MobileCodeWS();
// 獲取具體的服務類型get post soap1.1 soap1.2
MobileCodeWSSoap wsSoap = ws.getMobileCodeWSSoap();
String address = wsSoap.getMobileCodeInfo("13888888888", null);
System.out.println("手機歸屬地信息為:" + address);
}
}
【測試結果】:
手機歸屬地信息為:13888888888:雲南 昆明 雲南移動合家歡卡
