浅谈及实战Web Service

来源:互联网 发布:1099端口 java 编辑:程序博客网 时间:2024/05/16 13:03
  简要介绍下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元素)增加一个子元素用来存放一些友好的错误信息,然后在接收端就向用户显示出在这个子元素下的错误信息