webservice:Web Service Case Study: 认证考试申请服务来源: 发布时间:星期三, 2008年12月17日 浏览:52次 评论:0
柴晓路 ([email protected])
Chief Architect 2002年4月10日 本文是Web Service Case Study系列文章第 2篇在这篇文章中我将围绕个认证考试申请系统展开设计和讨论这个应用和本文系统区别主要是面向B2C模式应用着眼点在于如何将这个系统客户端插入到尽可能多公共平台、桌面系统中去同时借助这个Case Study我将着重讲解在Web服务设计时候如何有效地使用XML Schema设计系统中使用XML数据模式本文中针对应用例子是个认证考试系统应用背景如下:(以下陈述纯属虚构) UDDI-China.org是中国Web Services技术组织提供Web服务系列技术技术认证服务具体负责这个技术认证服务是UDDI-China.org下WSTA机构任何技术人员都可以向WSTA机构提出申请要求进行某项Web服务技术(比如XML Schema、SOAP、WSDL、UDDI等)技术认证般流程是要经过申请、修读相应课程、考试这 3个主要步骤WSTA认证考试系统就是为了管理和加速这个流程而开发套系统 在介绍具体系统流程的前我们先来看看这个系统实体关系图: Figure 1. 认证考试系统实体关系图 结合图1中我们系统中基本上可以有这样 3个主要流程:
经过系统分析设计人员认为以下实体是需要使用XML来描述:
="atitle2">XML Schema建模 ="atitle3">Application 首先我们给出Application文档XML Schema定义及其模式图示随后我们再详细解释模式细节
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualied" attributeFormDefault="unqualied">
<xs:element name="Application" type="applicationType">
<xs:annotation>
<xs:documentation>Application模式定义</xs:documentation>
</xs:annotation>
</xs:element>
<xs:complexType name="applicationType">
<xs:annotation>
<xs:documentation>Application类型定义</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="person" type="personType"/>
<xs:element name="company" type="xs:"/>
<xs:element name="experience" type="xs:"/>
<xs:element name="reference" type="xs:" minOccurs="0" maxOccurs="3"/>
<xs:element name="certicationID" type="xs:long"/>
<xs:element name="applicationDate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="personType">
<xs:annotation>
<xs:documentation>个人信息类型定义</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="personID" type="xs:long"/>
<xs:element name="name">
<xs:complexType>
<xs:sequence>
<xs:element name="surname" type="xs:"/>
<xs:element name="givenName" type="xs:"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="contact" type="contactType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="contactType">
<xs:annotation>
<xs:documentation>联系思路方法类型定义</xs:documentation>
</xs:annotation>
<xs:choice>
<xs:element name="email"/>
<xs:element name="phone"/>
<xs:group ref="mailAddress"/>
</xs:choice>
</xs:complexType>
<xs:group name="mailAddress">
<xs:sequence>
<xs:element name="streetAddress" type="xs:"/>
<xs:element name="postCode" type="xs:"/>
</xs:sequence>
</xs:group>
</xs:schema>
上面代码给出了ApplicationXML Schema文档其中定义了个Application元素这个元素是Application数据文档根元素Application元素使用了applicationType这个复合类型作为它类型定义而applicationType类型定义引用了personType这个类型定义作为个人信息描述personType类型定义中使用了contactType类型定义来描述个人联系方式而contactType类型定义还使用了mailAddress这个组定义以支持choice定义方式 在详细介绍这个层次结构的前我们可以先来看看图2模式图示 Figure 2. Application模式图示 applicationType复合类型用于描述个申请表applicationType复合类型定义包含了6个子元素:person、company、experience、reference、certicationID、applicationDate分别表示个人信息、所属公司、工作经验、参考技能认证、认证考试ID、申请日期其中person类型是复合类型personType而其他5个元素都是简单类型company、experience、reference类型都是串xs:certicationID类型是xs:long而applicationDate类型是xs:date其中除reference出现次数可以是0到3次以外其他元素都是出现且仅出现1次 person子元素应用了personType复合类型personType复合类型定义包含了3个子元素:personID、name和contact分别表示个人ID、姓名和联系思路方法personID是个简单类型元素类型为xs:longname是个复合结构包含了两个子元素surname和givenName共同描述了人姓名 而contact子元素则是应用了contactType复合类型定义contactType是个选择类型应用contactType类型元素可以选择是包含个email子元素、或是包含个phone子元素或是包含个mailAddress子元素mailAddress使用了在后面定义元素组定义mailAddress 为了使得对contact元素定义理解地更为具体些我们下面给出些contact元素例子表示例子具体包含在person元素内
<person>
<personID>20302290</personID>
<name>
<surname>Joe</surname>
<givenName>Huang</givenName>
</name>
<contact><email>[email protected]</email></contact>
<contact><email>[email protected]</email></contact>
<contact>
<mailAddress>
<streetAddress>No.2000, Huangxing Road, Shanghai</streetAddress>
<postCode>200433</postCode>
</mailAddress>
</contact>
</person>
上面代码给出了个person例子文档其中这个个人信息包含了 3个联络方式两个是email地址个是寄信地址此人没有留下联系电话 最后我们给出Application模式个完整例子文档
<?xml version="1.0" encoding="UTF-8"?>
<Application>
<person>
<personID>20302290</personID>
<name>
<surname>Joe</surname>
<givenName>Huang</givenName>
</name>
<contact><email>[email protected]</email></contact>
<contact><email>[email protected]</email></contact>
<contact>
<mailAddress>
<streetAddress>No.2000, Huangxing Road, Shanghai</streetAddress>
<postCode>200433</postCode>
</mailAddress>
</contact>
</person>
<company>Innoteck Company</company>
<experience> Architect of Innoteck</experience>
<certicationID>X00910</certicationID>
<applicationDate>2002-2-18</applicationDate>
</Application>
="atitle3">CourseSession 同样我们先给出CourseSessionXML模式文档CourseSession用于描述门课程某个学期安排
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualied" attributeFormDefault="unqualied">
<xs:element name="CourseSession" type="CourseSessionType">
<xs:annotation>
<xs:documentation>CourseSession Schema Definition</xs:documentation>
</xs:annotation>
</xs:element>
<xs:complexType name="CourseSessionType">
<xs:sequence>
<xs:element name="Course" type="CourseType"/>
<xs:element name="Session" type="SessionType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SessionType">
<xs:sequence>
<xs:element name="CourseSessionID" type="xs:long"/>
<xs:element name="CourseLocation" type="xs:"/>
<xs:element name="CourseDate" type="CourseDateListType"/>
<xs:element name="Teacher" type="EmployeeType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CourseType">
<xs:sequence>
<xs:element name="courseID" type="xs:long"/>
<xs:element name="certicationID" type="xs:long"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="CourseDateListType">
<xs:list itemType="xs:date"/>
</xs:simpleType>
<xs:complexType name="EmployeeType">
<xs:complexContent>
<xs:extension base="personType">
<xs:sequence>
<xs:element name="jobTitle"/>
<xs:element name="department"/>
<xs:element name="roomNumber"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="personType">
<xs:sequence>
<xs:element name="personID" type="xs:long"/>
<xs:element name="name">
<xs:complexType>
<xs:sequence>
<xs:element name="surname" type="xs:"/>
<xs:element name="givenName" type="xs:"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="contact" type="contactType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="contactType">
<xs:choice>
<xs:element name="email"/>
<xs:element name="phone"/>
<xs:group ref="mailAddress"/>
</xs:choice>
</xs:complexType>
<xs:group name="mailAddress">
<xs:sequence>
<xs:element name="streetAddress" type="xs:"/>
<xs:element name="postCode" type="xs:"/>
</xs:sequence>
</xs:group>
</xs:schema>
其中复合类型personType、contactType以及元素组mailAddress定义和前面代码中Application模式文档中定义是样在这个文档中我们给出这部分定义是为了EmployeeType定义需要在这里EmployeeType类型定义扩展继承了personType类型定义 其次CourseSession模式文档其他部分分别定义了CourseSessionType、CourseType和SessionType 3个复合类型以及个列表类型CourseDateListType在详细介绍这些类型定义的前我们先给出CourseSession模式图示以加深形象认识 Figure 3. CourseSession模式图示 下面我们结合图3模式图示来讲解下CourseSession模式定义 课程学期安排描述CourseSession由两部分组成(定义在CourseSessionType中):Course课程和Session学期安排其中Course子元素应用了CourseType复合类型该复合类型包含了两个子元素CourseID和certicationID分别表示这个课程ID标识以及这个课程对应认证考试ID标识而Session子元素则是应用了SessionType复合类型该复合类型包含 4个子元素:CourseSessionID、CourseLocation、CourseDate和TeacherCourseSessionID、CourseLocation是两个简单类型子元素分别表示课程学期安排标识ID以及课程授课地点CourseDate是个列表类型元素它值是日期列表表示课程授课时间而Teacher子元素应用了EmployeeType复合类型表示该课程这个学期授课老师 其中EmployeeType复合类型定义扩展继承了personType类型定义有关扩展继承特性在这里暂时先不详细介绍我将在后面章节中给出描述细节 最后按照前面惯例我们给出CourseSession模式个例子文档作为本节结尾
<?xml version="1.0" encoding="UTF-8"?>
<CourseSession>
<Course>
<CourseID>X0091001</CourseID>
<certicationID>X00910</certicationID>
</Course>
<Session>
<CourseSessionID>X009100120020220</CourseSessionID>
<CourseLocation>Shanghai Education Center</CourseLocation>
<CourseDate>2002-2-20 2002-2-22 2002-2-26</CourseDate>
<Teacher>
<personID>10307827</personID>
<name>
<surname>Mike</surname>
<givenName>Liu</givenName>
</name>
<contact><email>[email protected]</email></contact>
<contact><phone>13717652090</phone></contact>
<contact>
<mailAddress>
<streetAddress>No.1 UDDI-China Way, Shanghai</streetAddress>
<postCode>200400</postCode>
</mailAddress>
</contact>
</Teacher>
</Session>
</CourseSession>
="atitle3">ExamSession 同样我们先给出ExamSessionXML模式文档ExamSession用于描述某门认证考试某场考试安排
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualied" attributeFormDefault="unqualied">
<xs:element name="ExamSession" type="ExamSessionType">
<xs:annotation>
<xs:documentation>ExamSession Schema Definition</xs:documentation>
</xs:annotation>
</xs:element>
<xs:complexType name="ExamSessionType">
<xs:sequence>
<xs:element name="Exam" type="ExamType"/>
<xs:element name="Session" type="eSessionType"/>
<xs:element name="finished" type="xs:boolean"/>
<xs:element name="ScoreReport" type="ScoreReportType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ExamType">
<xs:sequence>
<xs:element name="examID" type="xs:long"/>
<xs:element name="certicationID" type="xs:long"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="eSessionType">
<xs:sequence>
<xs:element name="examSessionID" type="xs:long"/>
<xs:element name="examLocation" type="xs:"/>
<xs:element name="examDate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ScoreReportType">
<xs:sequence>
<xs:element name="personID" type="xs:long"/>
<xs:element name="score" type="xs:eger"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
这个模式文档相对于Application模式文档和CourseSession模式文档来说比较简单在这个模式文档中主要为定义个XML文档元素ExamSessionExamSession元素应用了ExamSessionType复合类型ExamSessionType复合类型定义包含了 3个 4元素Exam、Session、finished和ScoreReport分别表示认证考试、认证考试某场考试安排、考试是否完成以及成绩单这个XML文档用于在客户端和服务器端互相交换ExamSession比如用户期望申请某项认证考试当然会希望获得所有相关ExamSession信息当某个ExamSession结束后这个XML文档也用于传输用户成绩 图4给出了这个XML模式模式图示通过这个模式图示大家应该能够更好地理解这个模式结构 Figure 4. ExamSession模式图示 最后我们按照这个模式文档给出它个例子文档作为本节结束
<?xml version="1.0" encoding="UTF-8"?>
<ExamSession>
<Exam>
<examID>EX00910</examID>
<certicationID>X00910</certicationID>
</Exam>
<Session>
<examSessionID>EX0091020020309</examSessionID>
<examLocation>Shanghai Education Center</examLocation>
<examDate>2002-3-9</examDate>
</Session>
<finished>true</finished>
<ScoreReport>
<personID>20302290</personID>
<score>92</score>
</ScoreReport>
</ExamSession>
="atitle2">应用模式演示 在这里我们将外部应用假设也加入到整个应用模式中来参照下图其中National Education Information Portal是个国家范围教育信息门户网站WebSite而Global IT Education Web Service则是个全球IT教育机构提供个在线Web服务它们都以这个认证考试申请系统Web服务客户端应用角色出现在应用模式中(以下应用模式发展流程完全属于应用假设其中所有实体和细节纯属虚构) Figure 5. 应用模式演示 如图所示Web服务认证机构WSTA开始向公众提供Web服务技术认证服务开始这个服务仅在机构内部工作工作人员通过手工或Email收取报名表格然后在自己桌面应用中为客户完成相关注册上课和考试等申请流程按照这种方式整个机构运行效率不高所有流程瓶颈集中在机构内部桌面应用上随着申请认证考试学员不断增多WSTA不得不使用其提供认证技术:Web服务技术来改造他应用完成认证考试各项申请逻辑被包装成EJB Web Service并部署在机构内部BEA Weblogic Application Server上而桌面应用也被升级以支持对Web服务(也就是成为了个Web Service Client)为了使得这个认证申请Web服务(WSTK Web Service)能够被更多人通过各种平台进入并使用这个Web服务被注册进了Public UDDI Registry并发布了它WSDL描述文档同时WSTA也积极和公共教育平台进行接触并尝试合作可能经过番接触国家教育信息门户(National Educastion Information Portal, NEIP)同意和WSTA进行系统对接以实现在NEIP平台上直接对WSTA提供Web服务技术认证考试处理申请流程NEIP采用是Microsoft .NET平台因此在这里实施了J2EE和.NET平台连接集成同时由于将自身注册入了Public UDDI RegistryWSTA认证考试申请服务有机会被更多外部平台集成使用如图中Global IT Education Web Service就是例Global IT Education通过对Public UDDI Registry搜索搜索全球提供IT认证机构WSTKWeb服务是处于搜索结果集中Global IT Education通过处理搜索到WSDL文档完成了对WSTKWeb服务绑定实现了Global IT Education Web Service和WSTK Web Service连接 下面我们按照图中序号标明顺序逐讲解在这个Web服务应用场景下各个组件是如何协同实施和运作:
既然这个认证考试申请服务是面向广大个人用户用户不但可以通过WSTK机构进行申请同时也可以通过任何集成了WSTK认证考试申请服务应用、平台、网站WebSite等使用这个认证考试申请服务对于WSTK而言使用用户越多就越证明WSTK认证考试申请服务成功而使用用户越多般而言也意味着和WSTK认证考试申请服务建立Web服务连接应用、平台或网站WebSite也越多然后任何事情都有其正反两方面影响如果使用用户非常多接入平台、应用数量也非常多话WSTK认证考试申请服务可用性以及连接持久性就成为了个非常非常关键问题 有关传统软件Software领域甚至是硬件领域中涉及稳定性、可用性和持久性方面我就不再在这里探讨了这不属于我们正面对基于Internet分布式应用环境这个分布式应用集成那么我们需要面对是什么呢? 如果WSTK认证考试申请服务这个Web Service所在系统发生崩溃或者系统维护原因WSTK不得不把这个服务临时迁移到备份服务器上服务所在服务器IP地址发生了变化甚至服务入口URL也可能发生了变化此时现存所有连接将不再有效(地址和入口都变了自然不会持续有效)那么快速地恢复连接是我们需要处理问题 回顾下以前我们在做EAI时候思路方法对每个相关模块/系统开发人员、维护人员发出通知要求他们更改相应代码这在企业内部情况尚好我们还是能够在定时间内通知到每个人然后各个模块依照人员技术能力和工作时间多少完成了连接恢复不过万负责某个模块技术人员出差或其他些原因无法更新相应代码那么这个模块将有段时间无法使用现在将这情况从企业内拓展到了企业间、机构和个人的间后情况似乎变得更为复杂相同意外情况往往导致非常恶劣后果 首先我们是否还能通知到每个和WSTK服务相连接企业或机构其中部分按照合约方式建立连接也许可以然而由于是位于区别企业的间协同存在问题同时还有大部分是通过查询Public UDDI Registry找到WSTK服务从而和WSTK服务建立连接应用这些应用维护者我们根本无法通过般途径找到他们如果仍然只能使用人和人交流方式那么这些连接将在段时间内中断如果服务被永久性地迁移了那么这些好不容易发展起来连接将从此中止 其次WSTK服务是个最终服务中间会有很多门户网站WebSite、机构网站WebSite以WSTK服务代理形式直接向最终用户提供服务如果WSTK服务质量出现问题这些门户网站WebSite、机构网站WebSite可能因他们自身网站WebSite、服务声誉问题而考虑是否以后还要在他们网站WebSite、服务中提供对WSTK认证考试申请服务对于最终用户而言他们使用就是这些网站WebSite、机构所提供服务他们并不知道最终WSTK认证考试申请服务才是最终服务提供者因此如果WSTK认证考试申请服务不工作他们就是认为是这些网站WebSite、机构服务不工作了 再次还有相当部分是直接被集成到终端用户桌面应用对于这种情况WSTK更是没有办法通过传统方式重建连接了…… 我们面临问题是很严峻不过由于我们采用是Web服务架构利用是UDDI作为我们服务发现机制因此这种服务连接恢复问题我们可以通过UDDI所提供机制来尝试解决 我们知道WSTK开始就把WSTK认证申请服务注册到了UDDI注册中心具体说是在UDDI注册中心中注册了个businessService(对应于这个服务)这个businessService中包含了个bindingTemplate用于描述这个服务技术规范标准其中包含了这个Web服务访问入口以及如何访问这个Web服务WSDL文档等等对于搜索UDDI Registry企业/机构而言他们需要得到就是bindingTemplate信息从UDDI注册中心中获得bindingTemplate信息集中数据表示了个指定远端Web服务规范标准例子这些企业/机构应用应当缓存Cache该信息并且使用这个规范标准通过该WSTK服务注册地址来访问这个WSTK Web Service 当使用从UDDI注册中心中获得并缓存Cache下来信息(入口等)进行发生失败时正确做法是去查询当初获得该数据UDDI注册中心并获取和其对应更新了bindingTemplate信息也就是说当个服务维护或灾难恢复发生迁移时旦迁移完成这个服务应当主动去更新在UDDI Registry中相应bindingTemplate记录对应于前面WSTK服务情形WSTK服务应当去更新其对应bindingTemplate中访问入口地址URL等 在使用Web服务中使用这样模式那么使用UDDI操作入口站点(Operator Site)商业实体就得以在不加重通信和协调开销情况下自动完成和大量合作伙伴服务恢复这过程详细式描述如下:
由于WSTK认证考试申请服务已经以Web服务方式架构起来了在成功应用定时间的后这个服务架构将成为个解决方案在定范围内实施推广个快速有效办法是将这个认证考试申请服务升级为个ASP服务供各种提供认证考试机构通过Internet租用这是个有效利用资源和盈利渠道不过此时我们面临情况将更加复杂由于是ASP服务般来说在ASP服务中租用者并不是ASP服务所有者他们各自服务入口可能是彼此区别但不排除彼此相同实现可能(比如通过提供区别用户名/密码但入口是个)同时这些入口信息并不是由租用者来管理事实上当ASP服务提供者更改入口地址也是可能发生异常情况此时仍然要求由服务提供者去更新bindingTemplate信息以满足服务迁移平滑性变得不再实际了 那么马上可以想到就是所有和这个ASP服务相关bindingTemplate都由ASP服务提供者来管理不过这仍然不切实际如此来就违背UDDI Registry搜索初衷了首先搜索者是要搜索商业实体businessEntity如果区别机构businessService都被保存在ASP服务提供者businessEntity下显然和用户搜索方式相悖同时对于businessService描述信息那些提供认证考试机构都期望自己来维护显然这不是个正确合适解决方案UDDI在bindingTemplate机制里面提供了个重定向思路方法来试图解决这个问题有关这个思路方法我将在本系列下篇文章中结合下个例子给出 大家对于这两个问题任何建议以及大家想到其他可能问题都欢迎到论坛来提出意见或给出评论 ="atitle2">参考资料
0
相关文章
读者评论发表评论 |
|