Webservice一種使用http發送SOAP協議數據的遠程調用技術, javascript
其中,遠程調用技術可理解爲: java
一個系統遠程調用另外一個系統的服務,目標獲取另外一個系統的業務數據 web
wsdl,全稱是web server definition language, ajax
是服務器端的定義語言,可理解爲是服務器端的使用說明書 瀏覽器
說明接口/類、方法、參數和返回值, 服務器
隨服務發佈成功自動生成XML格式文檔 app
文檔的結構圖 ide
<service> 服務視圖,webservice的服務結點,它包括了服務端點 函數
<binding> 爲每一個服務端點定義消息格式和協議細節 工具
<portType> 服務端點,描述 web service可被執行的操做方法,以及相關的消息,
經過binding指向portType
<message> 定義一個操做(方法)的數據參數(可有多個參數)
<types> 定義 web service 使用的所有數據類型
閱讀順序: 由下向上
1. 概述:
soap是一種在http上傳輸的xml格式的數據,
能夠跨防火牆(http協議的端口是80,不會被攔截),
能夠跨平臺(因爲soap是由xml傳輸數據,xml是跨平臺,所以soap也能夠跨平臺),
SOAP = HTTP + XML ,並非webservice的專有協議
2.協議結構:
必需有 Envelope 元素,將整個 XML 文檔標識爲一條 SOAP 消息
可選的 Header 元素,包含頭部信息
必需有 Body 元素,包含全部的調用和響應信息
可選的 Fault 元素,提供有關在處理此消息所發生錯誤的信息
3.SOAP的版本
版本主要是1.1版本和1.2版本
共同點:
請求方式相同,都是post請求
協議的格式相同,都含有envlope和body標籤
不一樣點:
content-type不一樣:
1.1版本中,Content-type: text/xml; charset=utf-8,
1.2版本中, Content-Type: application/soap+xml; charset=utf-8;
命名空間不一樣:
1.1版本中, <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
1.2版本中, <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
uddi目錄服務,提供webservice服務端的註冊和搜索功能
服務器端開發主要包括三個步驟:
步驟一: 開發接口
package cn.xiaoge.ws.server;
public interface WeatherInterface {
public String getWeather(String cityName);
}
步驟二: 開發接口的實現類(實現類上必定要添加@webService 註解)
public class WeatherInterfaceImpl implements WeatherInterface {
@Override
public String getWeather(String cityName) {
System.out.println("服務鏈接中...");
String weather = cityName + ":晴...";
return weather;
}
}
步驟三: 發佈服務(利用Endpoint的publish方法進行發佈)
public class WeatherServer {
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:12345/weather", new WeatherInterfaceImpl());
}
}
確認是否發佈成功:
在瀏覽器地址欄中輸入: http://127.0.0.1:12345/weather,查看是否有內容顯示
文檔說明在http://127.0.0.1:12345/weather?wsdl中
客戶端開發包括四個步驟:
1.解析服務文件
在命令窗口中,定位到解析文件後要存放的位置,輸入命令:
wsimport –s . http://127.0.0.1:12345/weather?wsdl
2.建立服務視圖
WeatherInterfaceImplService weatherInterfaceImplService =
new WeatherInterfaceImplService();
3.建立實現類的實體
WeatherInterfaceImpl weatherInterfaceImpl =
weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class);
4.調用實體類中的方法
String weather = weatherInterfaceImpl.getWeather("北京");
5.打印結果
System.out.println(weather);
注意:解析後的文件儘可能不要與原始的服務端文件放到同一個包或項目
命令wsimport是jdk提供的一個根據使用說明書(WSDL地址)生成客戶端代碼工具
命令wsimport位置:%JAVA_HOME%\bin
命令wsimport經常使用的參數:
-d,默認的參數,生成*.class文件
-s,生成*.java文件
-p,指定代碼的包名,若是不輸入該參數,默認包名是WSDL中命名空間的倒序
命令wsimport僅支持SOAP1.1客戶端的生成
步驟一: 解析服務
wsimport -s . 服務的wsdl
步驟二: 建立服務視圖
WeatherInterfaceImplService weatherInterfaceImplService =
new WeatherInterfaceImplService();
步驟三: 建立實現類的實體
WeatherInterfaceImpl weatherInterfaceImpl =
weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class);
步驟四: 調用實現類的方法
String weather = weatherInterfaceImpl.getWeather("北京");
步驟五: 打印結果
System.out.println(weather);
步驟一:解析服務 生成客戶端代碼
命令: wsimport -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
步驟二:建立服務視圖
//1 建立url
URL url =
new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
//2 建立QName(NameSpace的最後必定要加」/」)
QName serviceName =new QName("http://WebXml.com.cn/", "MobileCodeWS");
//3 建立service
Service service = Service.create(url, serviceName);
步驟三:建立實現類的實體
MobileCodeWSSoap mobileCodeWSSoap = service.getPort(MobileCodeWSSoap.class);
步驟四:調用實體類中的方法
String mobileCodeInfo = mobileCodeWSSoap.getMobileCodeInfo("13666666666", "");
步驟五:打印結果
System.out.println("13666666666的詳細信息:"+mobileCodeInfo);
步驟一:建立服務地址
//1.建立服務地址(是服務的地址,不是服務的視圖)
URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");
步驟二:打開一個通向服務的鏈接
//2.打開一個鏈接
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
步驟三:設置鏈接的參數
//1.設置請求方式
urlConnection.setRequestMethod("POST");
//2.設置請求的格式
urlConnection.setRequestProperty("content-type", "text/xml;charset=utf-8");
//3.設置輸入輸出權限
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
步驟四:組織soap協議,準備發送給服務器端
String soapxml = getXml("15512345678");
OutputStream os = urlConnection.getOutputStream();
os.write(soapxml.getBytes());
步驟五:接收服務器端的響應,並打印
//判斷響應碼是不是200
if(200 == urlConnection.getResponseCode()){
//準備輸入流
InputStream is = urlConnection.getInputStream();
//將inputStream封裝成字符流
InputStreamReader isr = new InputStreamReader(is);
//將字符流成bufferedInputStream
BufferedReader br = new BufferedReader(isr);
//接收拼接數據
StringBuffer sb = new StringBuffer();
//臨時數據接收
String temp = null;
if((temp = br.readLine()) != null){
sb.append(temp);
}
System.out.println(sb.toString());
//關閉資源流
br.close();
isr.close();
is.close();
}
os.close();
其中,在第四步中,用到了getXml(String phonenum);方法,具體代碼以下:
public static String getXml(String phoneNum){
String soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+"<soap12:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
+"<soap12:Body>"
+"<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
+"<mobileCode>"+phoneNum+"</mobileCode>"
+"<userID></userID>"
+"</getMobileCodeInfo>"
+"</soap12:Body>"
+"</soap12:Envelope>";
return soapXml;
}
步驟一:
準備頁面
<body>
<input type="text" id="phoneNum"/>
<input type="button" value="查詢" onclick="javascript:getMobileInfo();"/>
</body>
步驟二:
準備ajax
<script type="text/javascript">
function getMobileInfo(){
//1.準備xmlHttpRequest
var xhr;
if (window.XMLHttpRequest) { // 適用於全部新型瀏覽器
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // 適用於IE5.0 與 IE6.0
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
//2.打開鏈接
xhr.open("post", "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx", true);
//3.註冊回調函數
xhr.onreadystatechange=function(){
//判斷請求是否發送成功,且相應是否成功
if(4 == xhr.readyState && 200 == xhr.status){
//若是相應成功,就打印數據
alert(xhr.responseText);
}
}
//4.設置請求頭,準備soap數據
xhr.setRequestHeader("content-type", "text/xml;charset=utf-8");
var soapxml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+"<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
+"<soap12:Body>"
+"<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
+"<mobileCode>"+document.getElementById("phoneNum").value+"</mobileCode>"
+"<userID></userID>"
+"</getMobileCodeInfo>"
+"</soap12:Body>"
+"</soap12:Envelope>";
//判斷是否拼裝成功
alert(soapxml);
//5.發送數據
xhr.send(soapxml);
}
</script>
@WebService-定義服務,在public class上邊
targetNamespace:指定命名空間
name:portType的名稱
portName:port的名稱
serviceName:服務名稱
endpointInterface:SEI接口地址,若是一個服務類實現了多個接口,只須要發佈一個接口的方法, 可經過此註解指定要發佈服務的接口。
@WebMethod-定義方法,在公開方法上邊
operationName:方法名
exclude:設置爲true表示此方法不是webservice方法,反之則表示webservice方法
@WebResult-定義返回值,在方法返回值前邊
name:返回結果值的名稱
@WebParam-定義參數,在方法參數前邊
name:指定參數的名稱
注意:註解都標註在服務的實現類中,不要標記錯位置
@WebService(
targetNamespace="http://weather.xiaoge.cn/",
serviceName="WeatherWS",
portName="WeatherWSSoap",
name="WeatherWSSoap"
)
public class WeatherInterfaceImpl implements WeatherInterface {
@Override
@WebMethod(operationName="getWeather")
public @WebResult(name="weather") String getWeather( @WebParam(name="cityName") String cityName) {
String weather = cityName + ":晴...";
return weather;
}
}
經過註解,能夠更加形像的描述Web服務。對自動生成的wsdl文檔進行修改,爲使用者提供一個更加清晰的wsdl文檔.
當修改了WebService註解以後,會影響客戶端生成的代碼。調用的方法名和參數名也發生了變化,此時若是調用服務端須要從新生成客戶端代碼.