簡要介紹下soa及個人對webservice的理解.就一個具體的項目介紹下實施過程中一些需要注意的問題
 引用文章:
 (1) http://webservices.xml.com/pub/a/ws/2003/09/30/soa.html
 (2) ms-help://ms.vscc.2003/ms.msdnqtr.2003feb.2052/cpguide/html/cpconanatomyofsoapwebservicelifetime.htm
 (3) ms- help://ms.vscc.2003/ms.msdnqtr.2003feb.2052/cpguide/html/cpconcustomizingsoapinaspnetwebserviceswebserviceclients.htm
 
 
“話說天下大事, 分久必合,合久必分.”(三國演義)----軟件行業是不是也一樣呢?
 
現在的軟件行業有著各種各樣的技術平臺,體系架構,但由于不同平臺關注的方面不一樣,各有各自的特色,平臺之間很難溝通,從而形成一個個的信息孤島.那如何把這些信息孤島聯系在一起呢.?業界提出了很多的方案,一個很著名的方案就是 serviced-oriented (面向服務).那面向服務是什么呢?這是對它的定義:“soa is an architectural style whose goal is to achieve loose coupling among interacting software agents. a service is a unit of work done by a service provider to achieve desired end results for a service consumer. both provider and consumer are roles played by software agents on behalf of their owners.”(1).面向服務是一系列服務的集合.各個服務之間可以互相通信(包括簡單的數據傳遞和多個服務共同參與一個活動) ,它通過為各個系統提供一些外部接口,從而達到集成各個系統的目的.業界也有些相對應的體系架構,例如: dcom.corba.j2ee.但都無法徹底實現跨系統的集成.個人覺得原因如下:
1. 接口定義語言無法被不同系統所接收.無論是dcom.cobra 還是j2ee都有各自的接口定義語言(都是二進制的).它們都無法被其他系統所接受.而接口一旦被設定就很難改變.而用戶的需求是在不斷變化的.
2. 使用的是二進制的網絡協議來進行數據通信.很難跨過防火墻,而且各自使用的協議沒有被廣泛的接收,這點對internet的運用尤為關鍵
這時一種新的體系架構出現了,它就是xml web services,微軟對它的定義是 : “xml web services 是提供特定功能元素(如應用程序邏輯)的可編程實體,任何數量的、可能是完全不同的系統都可以用常見的 internet 標準(如 xml 和 http)訪問它。它的核心特征是存在于服務的實現與使用之間的高度抽象化。” web services正在迅速的被各個平臺所接受.相對于其他架構,它的優勢在與:
1. 接口定義語言.它使用wsdl作為接口定義語言.這是一種基于xml格式的document ,而文本是可以被各種系統和平臺所認識的.
2. 使用http,soap,smtp等其他被廣泛接受的協議進行數據通信.而http是internet的基礎協議之一
 
那如何深入的理解web services呢?個人覺得應從以下幾個方面入手:
一. 目的
它是實現soa的一種方式,是為了連接不同的系統和計算設備.實現系統和數據的互操作性
簡單的說是要能夠訪問不同的系統和計算設備中的數據.而不用關心這些數據在各自系統和設備中是如何存放的.也可以說成不用關心數據是如何封裝的(類似oo里的黑盒)
二. 定義
xml web service顧名思義就是使用xml來提供web服務.其實嚴格的說web可以不要,就是xml service,因為并不是所有的web service都需要webserver的.服務就是把我有的功能提供給使用者,也就是向使用者提供一個接口,這就是web service.因此web service絕對不是一種新的分布式對象.而dcom , corba,j2ee 本質上都是分布式的對象.
三. 組成
1. 一些能處理xml的組件.
首先xml web service(或者web service)要能夠處理xml,至于處理xml的組件是如何設計的.不同語言,平臺有不同的方式.可以是oo(面向對象)的.也可以是其他方式.在.net里是通過.net framework 提供的一些類實現的
 
2. xml 文檔
前面我們說過web service優勢之一在與接口定義語言(idl)是基于xml的文檔,由于web service 是soa(面向服務)的一種,而soa的目標是在系統之間建立一種松散的耦合,因此服務和消費服務方就不能以object作為數據溝通的紐帶或者說鍥約(contract) ,就必須使用xml文檔來做為鍥約.那為了使服務提供方和消費方都能夠理解contract的含意.web service使用wsdl來描述xml文檔.即描述對外的接口.同時使用xml schema來描述文檔里的數據
3. xml文檔的載體
有了xml文檔就需要一個承載它的協議.web service使用soap作為載.soap:簡單對象訪問協議,嚴格來說這個名稱是錯的,因為它不是用來訪問對象的.ms給它的定義是” soap 是一種基于 xml 的、用于在 web 上交換結構化和類型信息的簡單的輕量協議”.它以信封的方式來承載xml文檔.信封分為兩部分: 信封頭(head) 和信封體(body).頭一般用來保存一些輔助的信息,例如安全(簽名和加密數據)和路由信息,信封體用來保存鍥約即服務的接口描述和具體的數據
4. 服務的地址
 用來告訴服務消費方從哪里可以訪問服務,服務位于何地,對此
 microsoft提供了uddi(通用說明、發現和集成).
 
net 實現web service的方式是通過asp.net.它封裝了很多的細節,使開發人員開發webservice很方便,但造成的結果是使認識本質比較困難.(ms的一貫作風).
 l 通過web方法的形式來調用web service.
 前面說了web service之間交換的實際上是xml文檔,考慮到很多程序員 
 不習慣直接操作xml(喜歡操作對象及其方法),在.net里將接收到的
 xml文檔轉換成對象或作為方法的參數的值,同時又會將得到的值或對
 象反序列化成xml文檔發送回服務消費者,服務消費者就可以以傳統的
 調用對象的方法的形式來向服務提供者發送請求從而獲得希望的數
 據.從消費者提出服務申請到得到相應的結果的流程如下(2)-:
 
 
 由這個流程圖(2)可以看到.客戶端要調用web service首先要發送消息.
 而服務端是通過消息知道有消費者要調用它.因此從某種意義上說.web 
 service是一種基于消息的體系架構,只不過消息是基于xml的文檔
 l 代理類的產生
 代理類的作用是用來方便和web服務進行通信的.在.net 里可以以自動和手
 動的方式產生,兩者都是根據服務的wsdl文件產生的.正如前面所說為了方便
 程序員的習慣用法,.net會將xml文檔反序列化成對象,在代理類里也是同樣的.
 這樣就會給我們一種錯覺,好像在客戶端重新生成了服務端的對象.例如: 一個
 web方法 test向客戶返回一個objecta
 public class objecta 
 {
 public string fielda 
 public string fieldb
 }
 那么在代理類同樣會生成一個objecta.它的結構和服務端的objecta是一模一
 樣的.但實際上這只是.net為了方便我們使用web service而人為生成的(這也是
 很多人認為webservice是用來進行遠程對象訪問的原因之一).對web服務客戶
 端而言,接收到永遠只有xml文檔,文檔里的數據是以xml schema描述的.至于
 怎么使用是各個web客戶端各自的特點,對.net而言它會將一些復雜的自定義
 的xml schema類型轉換成object.其他的一些客戶端就不會轉換成object.例如
 soap tookit.它會轉換成一個xml 節點(node)對象
 
 
下面就結合一個實際的項目來說明如何實施web service.
 
一. 項目概況
某公司有個現有產品producta.(pa) ,它需要獲得一些數據來進行業務處理.這些數據按地區和時間是會變化的,同時數據是由相應的政府機構定的,不同地區的政府機構的數據是不同的,每變動一次都需要以公函的形式通知產品用戶,或者由公司自己整理然后告訴用戶去更新.這樣就造成不同地區有不同版本,用戶升級困難,同時政府機構之間的數據很難溝通和對比
二. 解決方案
利用web service的功能,將所有政府機構的數據都公開(當然要權限的 j).產品(pa)作為webservice的客戶端可以實時訪問不同的數據,這樣產品和數據之間,數據和數據之間,用戶和數據之間都無縫的聯系在一起了
三. 具體實施
有了服務就有服務的兩個參與者:服務的提供者和服務的消費者
 對于產品(pa)它是服務的消費者.因此它只是個web service client.可以是任
 何類型的程序.現有的pa是個vb版的程序,可以通過代理類來訪問不同 
 的 service.
 對于數據(a.b.c…….).它們即是服務提供者同時也是服務消費者.由于用戶
 需要能夠能直接查詢一些數據,因此對于用戶,我們給每個數據做了一個網站以
 方便用戶查詢(使用asp.net 建立)
 前面我們說了服務是將已有的功能和數據通過接口公開而不需要關心功能和
 數據在各自的系統中是如何實現的,因此對功能和數據本身依然可以采用既有
 的技術.實現功能和數據部分還是采用三層架構,將web service作為一個獨立的
 層(facade層).框架圖如下: 
 
 
.net提供了asmx文件作為具體實現的文件.在具體實施的過程中有幾個問題要注意:
 
l soap的格式
soap是服務鍥約的載體,它本身也有一定的格式.對于soap中的信封.有兩種格式 document和rpc.對于soap請求和響應中的數據有兩種格式: encoded 和literal. 
document 樣式是指將 body 元素格式化為 body 元素下的一個或多個連續的消息部分(3).是使用xsd schema的
rpc 樣式是指根據 soap 規范中對 rpc 使用 soap 的內容(也就是通常所說的 soap 規范的第 7 節)對 body 元素進行格式設置(3).它是將所有的元素封裝在一個xml元素中,不需要使用xsd schema
literal樣式是將參數駐留在 body 元素中并編碼為自包含的 xml 文檔.使用xsd schema
encoded樣式是使用 soap 規范中編碼規則進行格式設置的.它不需要xsd schema
 在asp.net中document/ literal是默認的設置.literal只能在document下才
 能使用,而encoded可以同時在document和rpc下使用.我們可以自定義
 soap的樣式..net提供了屬性來完成這個功能:
 soapdocumentmethod
 soapdocumentservice
 soaprpcmethod
 soaprpcservice
 具體的使用請參考msdn
 
l 實體(entity)的設計
項目中我沒有用dataset.用了自定義的類.主要的考慮是
a. 操作起來方便
b. dataset是個粗粒度的對象.包括一些我們不需要的屬性和對象.增加了訪問時間
如果web方法將實體作為參數時,需要對實體的有效性進行判斷.例如.實體中屬性內容是否為空,值的長度等等.由于.net會自動將接收到的xml消息反序列化成對象,而對象的值是客戶端設置的,我們無法控制.那這時就有必要進行數據有效性的判斷了.一般有三種辦法.
a. 在商業邏輯層進行驗證.
這樣的缺點時代碼量比較多,尤其時當屬性比較多的時候,改動不方便
b. 通過實體對應的xsd文件來進行驗證
c. 通過設置在實體屬性上的attribute來進行驗證
b和c都利用了反射技術來實現,優點是減少了代碼量,改動比較方便,推薦使用.我在項目里用了attribute的方法. 
 
l webservice的安全
安全性是web service 一個很重要的方面.
 安全主要包括授權和簽名這兩方面.microsoft和其他公司共同提出了一
 個工具包來解 決這個問題:web service enhancment(wse)- .現在最新
 的版本是2.0. 實現了很多重要的service規范..
 
l exception的實現
web service里通常會將異常以soap錯誤的形式發布.在soap消息中有個fault元素是專門用來保存這些信息的.在用asp.net創建的web service中是先將異常序列化然后放到fault元素中的.一般會將錯誤封裝成soapexception向客戶端拋出,但如果遇到了soap中header部分的錯誤就會拋出一個soapheaderexception.對于soapexception,錯誤信息是放在detail屬性里的,里面包含錯誤的詳細信息.在實際應用過程中這些詳細信息對客戶是不友好的,這時就需要我們重新封裝下soapexception了.方法是在拋出異常的服務端給detail屬性(序列化成detail元素)增加一個子元素用來存放一些友好的錯誤信息,然后在接收端就向用戶顯示出在這個子元素下的錯誤信息