1. Web Service 接口
1.1 接口方式說明和長處
在筆者的開發生涯中,看成爲接口提供商給第三方提供接口時,以及做爲client去調用第三方提供的接口時,大部分時候都是使用 Web Service接口, Web Service做爲接口使用普遍的緣由,與它的特色息息相關。 javascript
Web Service的主要目標是跨平臺的可互操做性,爲了實現這一目標, Web Service 全然基於 XML(可擴展標記語言)、 XSD( XML Schema)等獨立於平臺、獨立於軟件供應商的標準,是建立可互操做的、分佈式應用程序的新平臺。所以使用 Web Service有不少長處: php
1.1.1 跨防火牆的通訊 css
假設應用程序有成千上萬的用戶,而且分佈在世界各地,那麼client和server之間的通訊將是一個棘手的問題。因爲client和server之間通常會有防火牆或者代理server。要調用 Web Service,可以直接使用 SOAPclient,而後把它和應用程序鏈接起來。不只縮短了開發週期,還下降了代碼複雜度,並能夠加強應用程序的可維護性。
1.1.2 跨程序語言的應用程序集成 html
在企業的各類應用系統中,很是多系統不是使用一樣的語言編寫的,好比有的使用 Java,有的使用 php、 C#、 asp。當各類系統之間需要交互時,可以使用各類語言都通用的 WSDL定義接口,對外將需要的接口暴露給指定的客戶。 java
XML Web services 提供了在鬆耦合環境中使用標準協議( HTTP、 XML、 SOAP 和 WSDL)交換消息的能力。消息可以是結構化的、帶類型的,也可以是鬆散定義的。
1.1.3 軟件和數據重用 ajax
Web Service在贊成重用代碼的同一時候,可以重用代碼背後的數據。使用 Web Service,不再必像曾經那樣,要先從第三方購買、安裝軟件組件,再從應用程序中調用這些組件;僅僅需要直接調用遠端的 Web Service就可以了。 算法
還有一種軟件重用的狀況是,把好幾個應用程序的功能集成起來,經過 Web Service 「暴露 」出來,就可以很easy地把所有這些功能都集成到你的門戶網站中,爲用戶提供一個統一的、友好的界面。 編程
可以在應用程序中使用第三方的 Web Service 提供的功能,也可以把本身的應用程序功能經過 Web Service 提供給別人。兩種狀況下,都可以重用代碼和代碼背後的數據。 json
1.2 重要概念
1.2.1 何爲Web Service ?
Web Service是構建互聯網分佈式系統的基本部件,它是一個應用程序,它向外界暴露出一個能夠經過 Web 進行調用的 API 。這就是說,別人能夠用編程的方法經過 Web 來調用這個應用程序。 小程序
它經過標準通訊協議,在互聯網上以服務的方式公佈實用的程序模塊,眼下大部分是用 SOAP做爲通訊協議。
它提供一份具體的接口說明書,來幫助用戶構建應用程序,這個接口說明書叫 WSDL( Web服務描寫敘述語言, Web Service Description Language)。
一般已公佈的 Web Service要註冊到管理server,便於使用者查詢和使用。這個是經過 UDDI( 統一描寫敘述、發現和集成, Universal Discovery Description and Integration)來完畢的。
1.2.2 何爲 SOAP 協議?
SOAP定義 SOAP消息的 XML格式( XML格式),假設你用一對 SOAP標記( SOAP Elements)把 XML文檔括起來,那麼這個就是一個 SOAP消息。
SOAP規範還定義瞭如何用 XML來描寫敘述程序數據,如何運行 RPC( 遠程過程調用, Remote Procedure Call)。大多數 SOAP解決方式都支持 RPC-style應用程序,因爲很是多程序猿已對 DCOM或 CORBA熟悉。 它還支持 Document-style應用程序( SOAP消息僅僅包括 XML文本信息)。 Document-style應用程序有很是好的靈活性,因此很是多用 RPC很是難構建的 Web Service用這樣的方式構建。
最後 SOAP規範還定義了 HTTP消息是如何傳輸 SOAP消息的。這並不表明 SOAP僅僅能用 HTTP來做爲傳輸協議, MSMQ、 SMTP、 TCP/IP都可以作 SOAP的傳輸協議。
安全性對於應用程序來講是很是重要的。那麼 SOAP的安全性怎樣呢?對於把 HTTP做爲傳輸協議的 SOAP來講是沒有問題的,因爲 HTTP協議已經有很是好的安全構架。那麼用其它傳輸協議會出現安全問題嗎?這方面也已經有相關規範
( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnglobspec/html/ws-security.asp )。
1.2.3 何爲 WSDL ?
WSDL是一種 XML文檔,它定義 SOAP消息和這些消息是如何交換的。 IDL( Interface Description Language,接口描寫敘述語言)是用於 COM和 CORBA的, WSDL是用於 SOAP的。 WSDL是一種 XML文檔,因此可以閱讀和編輯,但很是多時候是用工具來建立、由程序閱讀。
舉個實例,當讀者需要使用第三方的 Web Service構建應用程序。你可以向接口提供商索取使用 WSDL文檔,在該文檔中具體的說明了各個方法的方法名、參數和參數類型等信息。在 Java等編程語言的 IDE(好比 My Eclipse)中,可以依據 Web Servie生成相應的測試代碼,略微改動一下就能夠。
1.2.4 何爲 UDDI ?
UDDI可以比喻成電話本,電話本里記錄的是電話信息,而 UDDI記錄的是 Web Service信息。可以不把 Web Service註冊到 UDDI。但假設要讓全球的人知道這個 Web Service,不妨註冊到 UDDI。
UDDI文件夾說明文件也是一個 XML文檔,它包含三個部分。「白頁( White Paper)」說明提供 Web Service的公司(人)信息,比方說名稱、地址和聯繫方式等等。「黃頁( Yellow Paper)」說明 UDDI文件夾的分類,比方說金融、服務和印刷等等。「綠頁( green Paper)」說明接口( Web Service 提供的)的具體信息。 UDDI提供多種查詢方式,來幫助你找到需要的 Web Service。假設你查詢與財務有關的 Web Service,那麼 UDDI會提供具體的信息。
1 .2.5 何爲 XML ?
XML( Extensible Markup Language)就能夠擴展標記語言,它與 HTML同樣,都是 SGML(Standard Generalized Markup Language,標準通用標記語言 )。在 Web Service接口中, WSDL和 UDDI文件夾文件都是一種 XML文檔, XML攻克了數據表示的問題。
1.2.6 何爲 XSD ?
XML攻克了數據表示的問題,但它未定義一套標準的數據類型,更沒有說怎麼去擴展這套數據類型。好比,整型數究竟表明什麼? 16位, 32位,仍是 64位?
W3C制定的 XML Schema(XSD)就是專門解決問題的一套標準。它定義了一套標準的數據類型,並給出了一種語言來擴展這套數據類型。 Web Service就是用 XSD來做爲其數據類型系統的。
1.3 開發 Web Service 接口和調用測試
在 Java IDE環境中開發 Web Service接口,以及怎樣調用第三方的 WSDL文檔怎樣進行接口測試的參考文章詳見:
1)《 使用XFire+Spring 構建 Web Service (一) ——helloWorld 篇 》:
http://www.blogjava.net/amigoxie/archive/2007/09/26/148207.html
2)《 使用XFire+Spring 構建 Web Service (二) 》:
http://www.blogjava.net/amigoxie/archive/2007/09/28/149074.html
3)《 依據wsdl 生成相應的 Java 代碼進行接口測試(一) 》:
http://www.blogjava.net/amigoxie/archive/2009/11/20/303038.html
1.4 開發舉例
1.4.1 做爲提供商提供hello world的接口
參見:《 使用XFire+Spring 構建 Web Service (一) ——helloWorld 篇 》:
http://www.blogjava.net/amigoxie/archive/2007/09/26/148207.html
1.4.2 做爲提供商提供用戶信息查詢接口
參見:《 使用XFire+Spring 構建 Web Service (二) 》:
http://www.blogjava.net/amigoxie/archive/2007/09/28/149074.html
2. js 接口
2.1 接口方式說明和優缺點
在開發的過程當中,也遇到過需要調用第三方接口的狀況,好比筆者在完畢的一個股票查詢的小 demo中,就需要調用新浪提供的股票查詢的 js接口。另外有一次,在系統中使用了第三方的 GIS系統,調用的也是 js接口。 因爲調用 js接口的門檻很是低,因此有的接口供應商會提供多種調用接口的方式,好比 Web Servivce接口和 js接口等。
對於瀏覽器來講, script標籤的 src屬性所指向資源就跟 img標籤的 src屬性所指向的資源同樣,都是一個靜態資源,瀏覽器會在適當的時候本身主動去加 載這些資源,而不會出現所謂的跨域問題。這樣咱們就可以經過該屬性將要訪問的數據對象引用進當前頁面而繞過 js跨域問題。固然,前提是接口必須是返回一段 js腳本,如一個 json對象數組定義的腳本:
modlist = [
{"modname": "mod1", "usernum": 200, "url": "/widget/info/1"},
{"modname": "mod2", "usernum": 300, "url" : "/widget/info/2"},
…
];
但 script標籤也有必定的侷限性,並不能解決所有 js跨域問題。 script標籤的 src屬性值不能動態改變以知足在不一樣條件下獲取不一樣數據的需求, 更重要的是,不能經過這樣的方式正確訪問以 xml內容方式組織的數據。
2.2 開發舉例
2.2.1 新浪股票查詢的js接口
功能說明 : stockDetail.jsp依據傳入的 stockId參數,調用新浪股票查詢提供的 js接口返回股票結果信息,並解析返回結果,將股票信息在頁面展現出來。
stockDetail.jsp代碼參考例如如下:
<%
@ page language = " java " contentType = " text/html; charset=UTF-8 " pageEncoding = " UTF-8 "
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<%
String stockId = request.getParameter( " stockId " );
if (stockId == null ) {
stockId = " 000001 " ;
}
%>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
/>
<
title
>
股票查詢結果
</
title
>
<
link
href
="<%=request.getContextPath() %>/css/style.css"
type
="text/css"
rel
="stylesheet"
>
<
script
type
="text/javascript"
src
="http://hq.sinajs.cn/list=s_sh<%=stockId %>"
charset
="gb2312"
></
script
>
<
meta
http-equiv
="pragma"
content
="no-cache"
>
<
meta
http-equiv
="cache-control"
content
="no-cache"
>
<
meta
http-equiv
="expires"
content
="0"
>
</
head
>
<
body
onload
=""
>
<
div
class
="bodyDiv"
>
<
table
>
<
tr
>
<
td
colspan
="2"
valign
="bottom"
align
="left"
style
="width:176px; background: url(<%=request.getContextPath() %>/images/line2_bg.gif) repeat-x;border-bottom: 1px solid #b0bec7;"
height
="19"
>
<
span
class
="titleFont"
>
<
font
class
="newTitleFont"
><
b
>
股票查詢結果
</
b
></
font
>
</
span
>
</
td
>
</
tr
>
<
tr
>
<
td
>
指數名稱:
</
td
>
<
td
><
span
id
="stockName"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
當前點數:
</
td
>
<
td
><
span
id
="currentPoint"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
當前價格:
</
td
>
<
td
><
span
id
="currentPrice"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
漲跌率:
</
td
>
<
td
><
span
id
="ratio"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
成交額(w):
</
td
>
<
td
><
span
id
=turnVolume
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
colspan
="2"
valign
="bottom"
align
="right"
style
="width:176px; background: url(<%=request.getContextPath() %>/images/line2_bg.gif) repeat-x;border-bottom: 1px solid #b0bec7;"
height
="19"
>
<
span
class
="titleFont"
>
<
font
class
="newTitleFont"
><
b
>
1日K線
0返回
</
b
></
font
>
</
span
>
</
td
>
</
tr
>
</
table
>
</
div
>
<
script
language
="javascript"
>
<!--
// 查詢結果的格式爲:指數名稱,當前點數,當前價格,漲跌率,成交量(手),成交額(萬元)
// 解析字符串
var stockValue = hq_str_s_sh <%= stockId %> ;
var stockArray = stockValue.split( " , " );
document.getElementById( " stockName " ).innerText = stockArray[ 0 ];
document.getElementById( " currentPoint " ).innerText = stockArray[ 1 ];
document.getElementById( " currentPrice " ).innerText = stockArray[ 2 ];
document.getElementById( " ratio " ).innerText = stockArray[ 3 ];
document.getElementById( " turnVolume " ).innerText = stockArray[ 5 ];
-->
</
script
>
</
body
>
</
html
>
帶上 6位 stockId參數(好比:值爲 000002),實時的 A股(代號爲 s_sh000002)查詢結果例如如下圖所看到的:
在文件頭部可看到例如如下一句引入了新浪提供的 js:
<
script
type
="text/javascript"
src
="http://hq.sinajs.cn/list=s_sh<%=stockId %>"
charset
="gb2312"
></
script
>
用例如如下語句得到經過接口查詢到的數據:
var stockValue = hq_str_s_sh
<%
=
stockId
%>
;
2.2.2 對外提供js接口
對外提供js接口僅僅需要經過<script src="..." type="..."/>請求的地址返回的是JSON字符串就能夠。
在本實例中,用到了筆者一篇 JSON文章的實例(《 JSON知識總結入門篇》: http://www.blogjava.net/amigoxie/archive/2010/09/25/332832.html ),在上面進行了小幅改動,簡便起見,沒有建立不論什麼的Java類,提供的對外的js接口是直接經過json.txt,經過該文件返回一個JSON字符串,在實際的應用狀況中,可以是一個Ation等。
json.txt定義了 JSON格式的字符串,並定義放在 json這個變量中, jsInterface.html文件請求遠端的一個路徑,然後解析返回的 JSON串,並打印出來。 json.txt在遠端的一個server上,好比該文件訪問地址爲: http://test.com/json.txt ,文件的內容例如如下:
var json={
"programmers": [
{ "firstName": "阿蜜果", "lastName":"McLaughlin", "email": "brett@newInstance.com" },
{ "firstName": "範範", "lastName":"Hunter", "email": "jason@servlets.com" },
{ "firstName": "高子", "lastName":"Harold", "email": "elharo@macfaq.com" }
],
"authors": [
{ "firstName": "安安", "lastName": "Asimov", "genre": "science fiction" },
{ "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
{ "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
],
"musicians": [
{ "firstName": "茂茂", "lastName": "Clapton", "instrument": "guitar" },
{ "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
]
}
在本地建立一個 jsInterface.html網頁,使用 <script type="text/javascript" src=」…」/>請求返回 json字符串的路徑信息,接着進行打印,該文件代碼例如如下:
<
html
>
<
head
>
<
title
>
JS Interface Test
</
title
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
>
<
script
type
="text/javascript"
src
="http://test.com/json.txt"
></
script
>
<
script
type
="text/javascript"
>
alert(json.programmers[ 0 ].firstName + ',' + json.programmers[ 0 ].lastName + ',' + json.programmers[ 0 ].email);
alert(json.programmers[ 1 ].firstName + ',' + json.programmers[ 1 ].lastName + ',' + json.programmers[ 1 ].email);
alert(json.programmers[ 2 ].firstName + ',' + json.programmers[ 2 ].lastName + ',' + json.programmers[ 2 ].email);
alert(json.authors[ 0 ].firstName + ',' + json.authors[ 0 ].lastName + ',' + json.authors[ 0 ].genre);
alert(json.authors[ 1 ].firstName + ',' + json.authors[ 1 ].lastName + ',' + json.authors[ 1 ].genre);
alert(json.authors[ 2 ].firstName + ',' + json.authors[ 2 ].lastName + ',' + json.authors[ 2 ].genre);
alert(json.musicians[ 0 ].firstName + ',' + json.musicians[ 0 ].lastName + ',' + json.musicians[ 0 ].instrument);
alert(json.musicians[ 1 ].firstName + ',' + json.musicians[ 1 ].lastName + ',' + json.musicians[ 1 ].instrument);
</
script
>
</
head
>
<
body
>
</
body
>
</
html
>
執行後可看到執行結果與《 JSON 知識總結入門篇》第一個實例的執行結果一致。
3. http 接口
3.1 接口方式說明和優缺點
需要爲第三方提供一個接口,原本打算繼續使用 Web Service接口,結果那邊的開發者說,他們沒有使用過 Web Service接口(是作 IPTV的一個公司),但願咱們能夠提供 http方式的接口。
另外咱們通常在提供 Web Sservice接口的同一時候,也對外提供 http接口。
3.2 開發實例
3.2.1 向http接口發送消息的使用小程序
本實例對本身提供請求信息爲xml格式的http接口,將xml格式的請求信息發給http接口的地址後,將調用接口的返回消息簡單的顯示在頁面,爲了簡便起見,筆者沒有對js代碼進行包裝。
該html文件代碼例如如下:
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=GB2312"
>
<
title
>
http interface test
</
title
>
<
meta
http-equiv
="pragma"
content
="no-cache"
>
<
meta
http-equiv
="cache-control"
content
="no-cache"
>
<
meta
http-equiv
="expires"
content
="0"
>
<
script
>
// XMLHttpRequest
var http_request = false ;
function send_request(method, url, content, responseType, callback)
{
http_request = false ;
// XMLHttpRequest
if (window.XMLHttpRequest)
{
// Mozilla
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType)
{
// MIME
http_request.overrideMimeType( " text/xml " );
}
} else if (window.ActiveXObject)
{
// IE
try
{
http_request = new ActiveXObject( " Msxml2.XMLHTTP " );
} catch (e)
{
try
{
http_request = new ActiveXObject( " Microsoft.XMLHTTP " );
}
catch (e)
{}
}
}
if ( ! http_request)
{
window.alert( " XMLHttpRequest create Error. " );
return false ;
}
if (responseType.toLowerCase() == " text " || responseType.toLowerCase() == " xml " )
{
http_request.onreadystatechange = callback;
} else
{
window.alert( " error responseType. " );
return false ;
}
if (method.toLowerCase() == " get " )
{
http_request.open(method, url, true );
} else if (method.toLowerCase() == " post " )
{
http_request.open(method, url, true );
http_request.setRequestHeader( " Content-Type " , " text/xml " );
} else
{
window.alert( " http method error. " );
return false ;
}
http_request.send(content);
}
function submitInfo()
{
var form = document.httpTestForm;
var pathInfo = form.pathInfo.value;
var xmlInfo = form.xmlInfo.value;
form.returnInfo.value = " wait
" ;
send_request( " POST " , pathInfo, xmlInfo, " xml " , showHttpTestBack);
}
function showHttpTestBack()
{
if (http_request.readyState == 4 )
{
if (http_request.status == 200 )
{
var responseInfo = http_request.responseText;
var form = document.httpTestForm;
form.returnInfo.value = responseInfo;
}
}
}
</
script
>
</
head
>
<
body
>
<
form
name
="httpTestForm"
action
=""
method
="post"
>
<
table
width
="100%"
border
="1"
>
<
tr
>
<
td
colspan
="2"
align
="center"
>
<
b
>
http interface Test
</
b
>
</
td
>
</
tr
>
<
tr
>
<
td
>
xmlInfo:
</
td
>
<
td
>
<
textarea
id
="xmlInfo"
name
="xmlInfo"
cols
="100"
rows
="5"
></
textarea
>
</
td
>
</
tr
>
<
tr
>
<
td
>
pathInfo:
</
td
>
<
td
>
<
input
type
="text"
name
="pathInfo"
value
="http://192.168.2.154:16000/Mbd/http/video"
size
="100"
/>
</
td
>
</
tr
>
<
tr
>
<
td
>
returnInfo:
</
td
>
<
td
>
<
textarea
name
="returnInfo"
id
="returnInfo"
cols
="100"
rows
="5"
></
textarea
>
</
td
>
</
tr
>
<
tr
>
<
td
colspan
="2"
align
="center"
>
<
input
type
="button"
name
="submitButton1"
value
="Submit"
onclick
="javascript:submitInfo()"
/>
</
td
>
</
tr
>
</
table
>
</
form
>
</
body
>
</
html
>
訪問該頁,頁面很是easy,輸入正確的 xml請求消息,和正確的路徑信息,點擊「 Submit」button,經過 ajax調用 httpport,並在成功取得信息後將返回結果顯示在最後一個文本框:
3.2.2 做爲提供商提供http接口
在這個實例中,server提供了一個 http接口,在這裏是一個 jsp頁面的訪問地址,實際應用過程當中,可以是 Servlet或 Action的訪問地址,在這個實例中,client發送 http get發送請求,帶上了 hotel(賓館信息)和 name(顧客姓名), http接口程序拿到參數信息後,依據必定算法檢查分配空暇房間號,這裏爲了簡便起見,僅僅是隨機的生成一個數字返回給client。 http接口的簡單程序 httpInterface.jsp例如如下所看到的:
<%
@ page language = " java " contentType = " text/html; charset=UTF-8 " pageEncoding = " UTF-8 "
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<%
Double room = 500 * Math.random();
out.write( " hotel= " + request.getParameter( " hotel " )
+ " ;name= " + request.getParameter( " name " )
+ " ;room= " + room.intValue());
out.close();
%>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
/>
<
title
>
http Interface
</
title
>
<
meta
http-equiv
="pragma"
content
="no-cache"
>
<
meta
http-equiv
="cache-control"
content
="no-cache"
>
<
meta
http-equiv
="expires"
content
="0"
>
</
head
>
<
body
>
</
body
>
</
html
>
可在 IE 上帶上參數訪問這個地址,可看到參考的結果信息,好比訪問 http://IP:port / 應用名稱 /httpInterface.jsp?hotel=motel&name=amigo ,參考返回結果例如如下:
hotel=motel;name=amigo;room=407
4. 參考文章
1)《 Web Service入門》: http://tech.it168.com/j/2007-09-09/200709092111735.shtml
2)《 Web Service簡單介紹特色 ,長處 ,缺點》:
http://hi.baidu.com/linjk03/blog/item/4ee93b03a5d29a8dd43f7cd5.html
3)《 Web Service百度百科》:
http://baike.baidu.com/view/67105.htm
4)《怎樣解決 js跨域問題》:
http://www.yaronspace.cn/blog/index.php/archives/542