中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> Bea专区 > BEA Workshop
BEA WebLogic Workshop 8.1™与Microsoft® Visual Studio.NET 2003 开发人员的效率及学习曲线的对…
作者:Heinrich Gantenbein 时间:2006-08-04 12:42 出处:bea.com.cn 责编:月夜寒箫
              摘要:BEA WebLogic Workshop 8.1™与Microsoft® Visual Studio.NET 2003 开发人员的效率及学习曲线的对比研究
  BEA 系统有限公司雇请IDesign进行了一次研究,研究内容为比较和对比在Visual Studio.NET 2003和WebLogic Workshop 8.1上构建类似的企业级应用功能时所需的相关效率级别、开发方法和域知识。IDesign是一家行业领先的.NET架构咨询和培训公司。

 

  本次研究包括在Visual Studio.NET 2003和WebLogic Workshop 8.1中开发业务逻辑、Web应用程序和Web services的结果。本次研究的目的在于:

  • 为Microsoft开发人员提供对在WebLogic Platform 8.1上构建J2EE应用程序的技巧和学习曲线的总体评估。
  • 比较和对比BEA WebLogic Workshop开发模型和方法与Microsoft的方法。
  • 比较和对比两种开发环境和开发模型中效率与灵活性的平衡。

  通过在使用两种开发框架——Visual Studio.NET 2003和BEA的WebLogic Workshop 8.1,开发一个结合了(同步的和异步的)业务逻辑、Web应用程序和(同步的和异步的)Web services的参考应用程序,并记载开发中的投入水平(level-of-effort)和全部体验,本次研究提供以上评估。

  本文的结论是,两种平台在用于开发企业级软件的架构和效率方面均十分相似。现在的Visual Studio.NET 2003程序员可以很快熟悉WebLogic Workshop环境,而且反之亦然。借助WebLogic Workshop 8.1,BEA已经成功地消除了编程复杂性,并使J2EE的学习曲线变得陡峭,同时维持与J2EE标准的兼容性,使具有其他平台和语言相关经验的开发人员可以很快掌握J2EE。

1.1 方法
  为了进行比较,IDesign联合Heinrich Gantenbein(一位经验丰富的.NET架构师)共同完成了下述工作:即使用Visual Studio.NET 2003在Microsoft .NET平台上重新构建了“BEA WebLogic Platform 8.1 评估版指南”中介绍的一个参考应用程序。本次研究将重点放在重新构建WebLogic 8.1评估版指南第1章中介绍的应用程序组件上,包括构建一个使用多种后端资源的复合业务逻辑层组件,一个使用该组件的Web站点,一个使用该组件并保护Web站点和Web service的Web service。

  下面的3.2节中详细描述了参考应用程序的要求和体系结构。评估版指南可以在BEA的dev2dev开发者社区站点http://dev2dev.bea.com/products/wlworkshop81/technicalguides/eval_guide81.jsp上找到。这篇白皮书概要介绍了IDesign的实现结果,并对两种方法进行了比较。

2. 执行概要
2.1 效率和方法之比较

  WebLogic Workshop和Visual Studio.NET 2003通过出色的IDE和可靠的框架成功地提高了编程效率。Workshop使用一种可视化的方法来开发用户界面、业务逻辑和Web services。Visual Studio.NET 2003使用一种可视化的方法来开发用户界面和设计数据库访问;然而,它对业务逻辑和Web services使用了一种基于代码的方法。

投入水平被衡量为:

  • 开发人员开发参考应用程序时需要编写的代码行数。
  • 实现参考应用程序所需表示的(可视化表示、菜单选择、向导步骤和属性窗格中的属性)数目。

对应用程序开发过程中所需投入水平的并行比较如下图所示:

  • 全部投入水平(包括构建Web services测试用具的工作)。
  • 仅对应用程序的投入(除去构建Web services测试用具的工作)。

上图表明:

  • 与Workshop相比,Visual Studio .NET 2003需要的表示较少,但代码行较多,因为它在业务逻辑和Web service中使用基于代码的方法。
  • WebLogic Workshop为复杂的Web services提供更好的集成Web services测试代码生成,从而为开发人员节约大量的工作。

下图显示了编程分类的详细信息。随后会给出详细的分析。

  也许,衡量投入水平更好的方式是在一个“总体投入”公式中结合表示和代码行的数量。对于这个公式,我假定编写一行代码的时间大约是执行一个表示的两倍。然而,这高度依赖于个人。作为一条通用法则,表示需要的技巧和域知识更少。下面的图表显示了对编程任务的总体投入(基于“总体投入”公式):

  这个图显示了可作如下解释的混合结果:

  • Visual Studio.NET 2003需要对“业务逻辑基础(Business Logic Basic)”另做一些投入,这是因为Enterprise Services(COM+)的使用。另外,IDesign坚定地相信,使用接口可以解除服务提供者和服务使用者之间的耦合;因此,我们使用显式的接口在.NET中实现了我们的业务逻辑,增加了所需的投入。WebLogic Workshop版本可以使用显式的接口;然而,示例应用程序使用了一个带有自动生成接口的类优先方法。
  • WebLogic Workshop的简单异步和事务化的编程模型解释了在“业务逻辑异步(Business Logic Async)”一项上的显著差别。Visual Studio.NET 2003将为更加复杂的异步事务化Queued Component模型承担很重的负担,因为该模型与Web services的集成并不好,尽管它是一个很好的通用异步编程模型。
  • Visual Studio.NET 2003在Web应用程序(Web Application)方面所需的投入要少的多,这主要是因为在J2EE for Form Bean中所需的投入和用于把Form Bean转换为内部对象的额外解析代码。这是一个常用的模式,但并不是实现这类代码的惟一方式。
  • WebLogic Workshop在异步的Web services类别(标记为“WS including Async”)方面获胜,因为它支持Web service的图形化编程和用于异步转换的简单属性设置。
  • 对于这个应用程序来说,WebLogic Workshop用于“松散耦合”的可视化模式映射相对Visual Studio.NET 2003的基于代码的方法并无显著优势。
  • 带有IIS的Visual Studio.NET 2003在实现SSL方面比Workshop有很大改进。Workshop可以得益于更多的配置文件编辑器。有一点很糟糕,即和WebLogic一样,IIS不提供开箱即用的测试证书。
  • Visual Studio.NET 2003带有用于WS-Security的“WSE 2.0 Preview”这个配置和策略文件编辑器,所以所需的XML配置文件编辑(用于Policy File)更少。Workshop中的策略文件编辑器与此不相上下。
  • WebLogic Workshop为Web services生成的测试页要高级的多。它不能生成的惟一测试是WS-Security for X509 certificate符号。Visual Studio.NET 2003无法在我们使用非原始类型作为参数或使用SOAP扩展时生成测试页。

2.2对程序员技能集的要求
  J2EE在复杂性方面是无可比拟的(原话出自O’Reilly出版的“Java Enterprise in a Nutshell”一书的992页)。Workshop使程序员可以以他们熟悉的方式访问J2EE,就像.NET允许以一种COM/ATL从未有过的方式访问基于组件的开发一样。

  Workshop对C# Visual Studio .NET 2003程序员来说非常亲切。他们只需要熟悉可视化的编程风格、Java Doc注释(作用类似于属性)和连接到被使用的Web service的代理(称为控件)。VB.NET程序员面临着同样的问题,另外还有转换为C++衍生语言的步骤。VB.NET程序员应该很容易适应可视化风格。

  对WebLogic Workshop 8.1感兴趣的Visual Studio.NET 2003用户应该下载WebLogic Workshop 8.1,然后按照本次研究用作基础的评估版指南中的指导行事。WebLogic Workshop 8.1开发人员许可证是免费的,可以从BEA的http://commerce.bea.com/showproduct.jsp?family=WLW&major=8.1&minor=0
页面下载。您可以在BEA的dev2dev开发人员社区站点的http://dev2dev.bea.com/products/wlworkshop81/technicalguides/eval_guide81.jsp页面上找到WebLogic Platform 8.1评估版指南。
(已有中文版的《WebLogic Platform实践指南出版》,中文版的Workshop帮助:http://dev2dev.bea.com.cn/techdoc/200403556002.html

2.3 优点和缺点

下表概括了不同编程模型的优点和缺点:

WebLogic Workshop 8.1 Visual Studio.NET 2003
一般 +更加图形化的设计器+为需要高度可伸缩性的应用程序提供对事务语义良好异步支持+IDE中的自动完成 +属性比JavaDoc更好+良好的自动完成功能+IDE、服务器的启动速度更快+在内存不足的情况下运行时,IDE的响应度仍然很好
Web站点 +图形化的页面流设计器+简单的安全性配置+丰富的内置控件库+借助使用Struts 1.1和MVC模式的Java Page Flow文件,促进逻辑与代码的分离 +简单的安全性配置+大量第三方控件+属性驱动的数据绑定+通过隐藏代码促进表示与逻辑的分离+无可视化的页面流设计器+行重定向以组织页面流
Web Service +简单的消耗+与.NET和其他平台的强大互操作能力+可以图形化地设计异步Web services和Web services转换+图形化的编译器+令人印象深刻的测试页面生成+基于XQuery解除内部签名和外部方法视图的耦合(使其松散耦合)+测试页面不能处理WS-Security +简单的消耗+灵活性+通过开放式Web services标准与其他平台相互操作的强大能力-异步的web services和web service转换必须使用定制代码和Queued Components(企业服务)来实现-基于代码的编译-测试页面只能处理简单的参数
控制逻辑 +图形化的编译器+接口自动生成-接口不是显式的-用于被使用控件的定制控件中的私有成员变量是由框架“魔法般地”实例化的 +在事务、池化方面具有灵活性+对ServicedComponents进行基于接口的开发-需要维护接口-基于代码的编译器
富客户端 -不可用,必须使用Java Swing API -借助轻松部署和安全性这样的沙箱,对富客户端提供强大的支持

2.4结论
  Visual Studio.NET 2003和Workshop的效率等级相似。精通C#的Visual Studio.NET 2003程序员应该在几周之内就能够熟练使用WebLogic Workshop。精通WebLogic Workshop 8.1的程序员应该在近似的时间内也能够熟练使用Visual Studio.NET 2003。

  对每种工具确切优点的讨论可能是无止境的。这两种产品都可以用于互操作,且口碑极佳。WebLogic Workshop项目可以使用.NET Web services,而Visual Studio.NET 2003项目可以使用WebLogic Web services。另外,开发WebLogic Web services的IT工作室还可以部署Visual Studio.NET 2003,借助internet部署的简单性开发使用以上任意一种Web services的富客户端。

  WebLogic Workshop的最大资产是其在由前至后的事务化异步编程过程中体现出来的简单性。它还提供一个用途广泛且设计良好的可视化编程模型。

  Visual Studio.NET 2003的最大优点是选择了更加现代的语言(VB.NET、C#等)和省时的构件,比如统一类型系统、委派和属性。此外,Visual Studio.NET 2003的响应度更高(使用Java的Swing库构建的应用程序,比如WebLogic Workshop IDE,速度还是赶不上本地的Windows客户端),所提供的编辑器也要稍微好一些。另外,Visual Studio.NET 2003的灵活性更高,因为它拥有更加灵活的框架(.NET用户可以控制确切的事务、并发性和池化行为),而且它对组件开发使用基于接口的方法。WebLogic Workshop用户可以转而进行J2EE编程,以获得相同的灵活性,而且不会降低效率。

3.架构
  本节将对两个平台之间的各自的技术集、IDE基本原理和应用程序架构设计模式进行比较。并且还简要地概览了所实现的应用程序。

3.1技术集
Microsoft集包括:

  • Windows 2000(任意版本)、Windows XP Pro或Windows Server 2003(任意版本)
  • SQL Server 2000
  • COM+(包含在上述操作系统内),一个提供池化、队列化、事务和其他企业应用程序服务的框架。这是Microsoft提供的与EJB应用服务器等价的框架。
  • .NET通用语言运行库(Common Language Runtime,CLR)1.1,一个类似于JVM的运行时系统(包含在Windows Server 2003内,或者可以免费下载用于其他操作系统的版本)。它理解面向对象和面向组件的构件(和JVM不同)。所有由CLR执行的代码(称为托管代码)都是JIT化的。CLR还负责代码访问安全(code access security,CAS)。
  • .NET Framework 1.1类库和CLR。这与JVM和java.*类等同。
  • IIS 5.1或6.0(包含在上述操作系统中),Microsoft的Web服务器。

ASP.NET,以IIS为宿主的.NET Web应用程序和Web services的执行引擎。

  • ADO.NET,一个到数据库(SQL Server、Oracle等)的托管代码接口。它类似于与JDO和Entity Java Bean联合使用的JDBC。
  • Enterprise Service,COM+的.NET表示。
  • C#或VB.NET,两种最常用于实现.NET应用程序的语言。它们是Java语言的.NET等价语言。
  • Visual Studio.NET 2003,用于所有.NET开发的IDE。

WebLogic和J2EE集包括:

  • 大多数操作系统,包括Unix、linux和Windows的多个版本。
  • Pointbase,包含在WebLogic 8.1开发套件中的DBMS。WebLogic支持大多数商业DBMS和所有JDBC提供程序。
  • BEA JRockit JVM(Java虚拟机)把已编译的Java应用程序中的字节码翻译为特定于平台的机器码,提供Java的可移植性。JVM支持Java运行时和类库。
  • WebLogic Server 8.1 Application Server提供核心应用程序基础架构服务给使用WebLogic Workshop和其他Java IDE构建的J2EE应用程序。应用服务器层支持用于开发表示和业务逻辑组件的J2EE API。
  • WebLogic Workshop 8.1 Application Framework,从处理应用程序的J2EE基础架构代码的J2EE API提供抽象层。
  • WebLogic Workshop 8.1 IDE,提供一个可视化的开发环境,以及用于在WebLogic 8.1上开发应用程序的完整源代码编辑器和调试器。
  • Java语言。Workshop需要基本的Java语法知识,但是不必了解整个J2EE API集。

3.2参考应用程序
3.2.1应用程序概览

  在这个项目中实现的应用程序是Avitek公司使用的一个在线定购物品应用程序。下面给出这个应用程序的一些业务前提,这些前提都摘自BEA WebLogic评估版指南:

  Avitek是一家大型的消费电子公司,需要增强他们的订单管理系统。Avitek的当前采用的方法是一个专有的、自主研发的订单管理流程,其中包括几个不同的系统。当今,只有少数几家发行商可以以电子方式提交产品订单给Avitek,而所有其他订单项都是手动完成的。此外,接收到订单之后,没有用于跨订单管理操作中涉及的大量后端资源来自动化业务流程的机制。任何试图增强当前订单管理系统的举动都必须利用和扩展现有的IT基础架构,因为这个基础架构是过去的20年中渐进开发的成果。这种对应用程序集成的需要折射出了之前对现代化的尝试过于复杂,而且代价无疑过于昂贵——而且“扯开替代”方法本应是错误的!
  Avitek的许多竞争对手最近都引入了另外的发行渠道。为了维护在行业中的竞争力,Avitek必须做出响应,增加其供货渠道。首先,通过提供一个允许最终用户直接从Avitek在线购买流行用品的Web应用程序,Avitek希望抓住对电子商务不断增长的需求。其次,Avitek想为所有的电子产品发行商和业务合作伙伴提供一个机会,使他们可以通过基于标准的Web services轻松地与Avitek的订单管理系统连接。

  在线定购物品应用程序给出一个支持同步的、基于Web浏览器的订单提交Web应用程序接口。它还给出一个支持异步的、高度可靠的应用程序到应用程序订单提交的Web service接口。

  下面的截图显示浏览器中的最终用户界面,表示产品分类。

  对于业务合作伙伴,XML订单请求和响应用在自动化应用程序的Web services
之间,以便异步地下订单和给出订单通知。

  为了服务于最终用户应用程序接口和业务合作伙伴Web service接口,选出了几种用例来实现。这些用例如下表所示:

用例 描述
客户登录 给定一个用户名称,检查它是不是我们数据库CRM系统中的有效客户
列出产品分类 访问产品数据库,获得产品名称、描述、基本价格和可用数量
构建一份订单 给定一个客户名称、一个产品列表和所需数量,使用适当的忠诚度折扣、税金、小计和总计构建一份订单
同步地下订单 给定一份订单,把它插入到数据库中,返回一个订单ID
异步地下订单 给定一个客户名称和一个产品列表,异步地构建一份订单并将其插入到数据库中。然后,执行一次到客户端的回叫,提供作为结果的订单ID

  两个表示层都利用了同样的核心业务逻辑把请求映射为正确的数据库交互。

3.2.2企业级需求
  在这个项目中开发的应用程序解决了企业编码中的几个常见功能需求。特别是这些需求包括:

  • 企业数据库访问
  • 封装好的、可重用的业务逻辑与表示逻辑分离
  • 基于标准,以确保与大量客户和合作伙伴间的互操作性
  • 灵活,以允许修改系统和在合作伙伴之间交换信息
  • 与现有数据、系统、应用程序和执行订单管理流程所需的业务逻辑集成
  • 调节与处理遗留系统和外部数据源相关的等待时间和服务中断
  • 可靠、可用和可伸缩,以满足不断增长的用户的需求,并维护他们在行业中的质量声誉

3.2.3 BEA WebLogic评估版指南
  在本次研究中开发的应用程序是首次使用BEA WebLogic Platform 8.1设计、构建,并记录在BEA WebLogic评估版指南中。您可以在BEA的dev2dev网站的http://dev2dev/products/wlworkshop81/technicalguides/eval_guide81.jsp上找到这份指南。该评估版指南引导WebLogic开发人员逐步地创建一个融合了WebLogic Platform 8.1主要功能的端到端应用程序。本次研究中构建的应用程序是基于第1章“应用程序开发解决方案”中的构建工作。

3.2.4 WebLogic实现架构

  以下显示了基于BEA的评估版指南中的指导,在WebLogic Workshop中为这个项目开发的系统主要组件:

  • 测试和浏览器层
    DigitalSignatureTest客户端(一个Web service),用于测试WS-Security。
    ¨ IE,用于测试常规的Web services(包括异步的)和Web应用程序。
    ¨ ASP.NET中的Web层
    ¨ OrderEntryWebService——Web service。
    ¨ AvitekWeb——Web应用程序。
  • 作为WebLogic控件(jcx)的中间层
    ¨ OrderEntryService。
    ¨ Callback Test——自动生成测试Web service以接收回叫。
    ¨ UserManagement——找不到用于封装用户创建、身份验证和组成员的所有交互的组件。BEA评估项目在Web站点中提供这些代码。因为它是业务逻辑,所以它属于中间层。
  • 数据访问层(模拟的)
    ¨ PricingService——一个模拟遗留定价服务的组件(EJB)。
    ¨ TaxCalculator——第三方(模拟的)Web service。
    ¨ SAP Products and Orders——模拟的SAP应用程序API(EJB)和预定义的jcx。
    ¨ Avitek.Commerce——模拟的内部遗留系统API(jcx)。

3.2.5 .NET实现架构
  以下显示了在.NET中为这个项目开发的系统主要组件:

  • 测试和浏览器层
    ¨ 需要编写用于测试WS(复杂的参数、异步或WS-Security)的OrderTest,OrderTestResponse。
    ¨ IE用于测试Web应用程序。
  • ASP.NET中的Web层
    ¨ AvitekOrderEntryWS是一个使用C#编写的、以ASP.NET为宿主的Web service。
    ¨ AvitekWeb使用VB.NET编写,以ASP.NET为宿主。
  • EnterpriseService ServicedComponents中的中间层(.NET中的COM+)
    ¨ OrderEntryService——在功能上与WebLogic中的OrderEntryServicejcx等价,使用C#编写。
    ¨ OrderEntryService.Queued,一个用于异步Web service使用的Queued Component,使用C#编写。
    ¨ UserManagement——封装用户创建、身份验证和组成员的所有交互的组件。BEA评估项目在Web站点中提供这些代码。因为它是业务逻辑,所以它属于中间层。
  • 数据访问层(模拟的)
    ¨ PricingService——模拟一个遗留定价服务的ServicedComponent(可能是使用C++编写的COM+或.NET ServicedComponent)。
    ¨ TaxCalculator——第三方(模拟的)Web service,使用C#编写。
    ¨ SAP Products and Orders——模拟的SAP应用程序API(使用SQL Server DB存储数据),使用C#编写为ServicedComponent。
    ¨ Avitek.Commerce——模拟的内部遗留系统API(使用SQL Server DB存储数据),使用C#编写为ServicedComponent。

3.3 IDE的架构和基本原理
  两种IDE(Visual Studio .NET 2003和WebLogic Workshop 8.1的IDE)都使用了多个窗格来组织工组区。Wrokshop Application或Visual Studio .NET 2003 Solutions用于分组当前的活动项目。中间的窗格用于显示代码或图形化设计器。每个窗格(中间的窗格除外)都可以通过拖放其句柄(Workshop中是接头(tab),而在Visual Studio .NET 2003中则是标题栏)进行重新布置。Visual Studio .NET 2003可以自动把很少使用的窗格隐藏在位于左边缘或右边缘的一个细条区域中(参见下面右边的Server Explorer)。这对于进行开发工作的掌上电脑非常有用(例如参加一个会议时),并使Visual Studio .NET 2003在这些环境中的效率更高。



  Visual Studio .NET 2003的自动完成功能比Workshop稍微好一点。此外,当开发人员意外地改变了缩进格式时,Workshop不会自动在卷曲花括号闭合之后重新格式化各个部分。Visual Studio .NET 2003的VB.NET自动格式化甚至比C#的也要好,这进一步增强了Visual Studio .NET 2003的领导地位。

  默认情况下,两种IDE都支持业务逻辑与表示逻辑分离。BEA产品大力倡导通过在Java Page Flow(*.jpf)中使用Struts,从而使用Model-View-Controller架构开发出松散耦合的系统。ASP.NET通过代码隐藏(code-behind)页面(*.aspx.cs)实现了开发松散耦合系统的目标。然而,它实际上不会映射到Model-View-Controller。实际的MVC模式的优点还有所争论(这种争论已经在本文的范围之外)。两种系统都提供分布式事务,以及遗留和第三方组件的集成。.NET拥有大量可用于简化软件构建的第三方组件。我使用Infragistic的网格控件来构造用于.NET解决方案的订单项页面。

  两者都使用了图形化的设计器、向导(其中有一些可以被再次调用,以便修改已经生成的代码),从而简化程序员的工作。它们广泛使用属性表以声明性的方式定制应用程序行为。只有当Workshop把UI和ADO.NET的开发扩展到组件集成和页面流逻辑时,Visual Studio .NET 2003才可以使用可视化的设计器来进行上述开发工作,因为这允许欠缺经验的用户获得更快的结果。

  为了支持可视化的设计范型,BEA不得不使用透明性较差的框架来限制灵活性,而Microsoft则使用一种透明的代码库方法(错误地命名为.NET Framework)。然而,Visual Studio .NET 2003的灵活性对其效率产生了负面影响,而且在某些情况下,灵活性是必需的。WebLogic Workshop用户可以通过在J2EE中进行编码而获得同样的灵活性,但是会显著降低效率。

  当然,两种环境使用不同的语言。.NET使用C#和VB.NET作为它的两种首要语言。C#和Java十分类似,可以视作Java的一种逻辑演变。VB.NET和C#语法不同,但是在理念、架构和语义等方面是相同的。C#(和VB.NET)支持对异步编程和时间处理的委派,这是一个统一的类型系统(需要时,原始类型就是对象)和属性。此外,Java对异常声明的需要使设计变得复杂(例如,EJB接口的本地和远程版本),并使得大型程序实际上更加难于维护(这与人们通常持有的观点——它将简化维护工作相反)。.NET属性是一种声明性的编程风格,而且它们也是可扩展的。WebLogic Workshop已经加入了一种类似于.NET属性的机制,形式是JavaDoc标签中的特殊注释。

C#: [InterfaceQueuing]
public interface IOrderEntry {…
Java: /** @common:message-buffer enable="true" */

3.4 Web应用程序
  ASP.NET和WebLogic Workshop在Web应用程序开发架构方面具有几乎具有一对一的相似性,但其底层架构有轻微的差别。

  WebLogic使用跨越多个相关页面的Java Page Flow(.jpf)把控制器与视图分离(MVC设计模式),而ASP.NET对每个页面使用隐藏代码的文件。二者均具有图形化的UI设计器,可以引导程序员使用良好的编码实践。JPF是位于Struts 1.1之上的瘦层,Struts 1.1是一个用于企业级Web应用程序开发的开源(Apache)框架。不幸的是,Struts是一个复杂的框架,但是JPF简化了它的使用。Workshop加入了一个图形化的流编辑器,用于集中管理页面流(参见下图)。在处理隐藏代码文件中的动作之后,ASP.NET需要为每次重定向编写一行代码。JPF在会话中处理实例数据和流,而.NET使用Session状态对象来维护信息。

Java Page Flow设计器:

  WebLogic Workshop和ASP.NET都使用数据绑定标签把数据源链接到实际的显示(将模型与视图分离)。WebLogic的首选方法是Form Bean和Struts 1.1,而.NET的首选方法是使用其本地的数据绑定API绑定到一个强类型的ADO.NET DataSet。Workshop程序员必须在html视图中插入标签,或者在dataSource属性中键入数据源名称,而Visual Studio .NET 2003程序员则从下拉列表中设置控件的DataBinding属性。两个系统都支持使用UI控件定制验证代码和归纳所构造的错误报告。.NET有几个用于特定验证的内置验证控件,而在Workshop中,实际的验证代码是手写的。

  ASP.NET允许每个页面请求使用自动完成启动事务(可选)。WebLogic认为每个动作是事务的开始。通常,.NET中的事务应该在中间层对象中启动,这鼓励程序员把所有的业务逻辑都转移到中间层中(优秀软件的一个必需属性)。

  WebLogic使用定制格式的身份验证方法进行用户身份验证,而且使用声明性的基于角色的安全性进行授权。ASP.NET有多种身份验证方法,从Windows身份验证到定制的Forms身份验证,并同时支持基于用户和基于角色的声明性和编程性授权。

3.5 Web Service
  BEA在Web services方面的基本原则是,它们必须是异步的、松散耦合的、事务化的和粗粒度的,以提高集成环境的企业级可伸缩性。这就是Web services的“BEA标准”,它渗透了WebLogic Workshop中的一切。Microsoft的平台以不同的方式支持同样的目标,同时提供另外的选择和编程模型。

  BEA和Microsoft把Web Services视作松散耦合业务系统和它们的平台与其他平台集成的关键技术。两个系统均允许程序员以开发常规组件的方式开发Web service。WSDL和其他支持项是自动生成的。两个系统均可以使用现有的WSDL生成实现骨架。它们之间的相似性到此为止。

  Workshop使用可视化的隐喻构建Web services。除了放入新方法之外,Web service所用控件中的任何方法都可以被拖放到设计器上,以生成传递调用。我建议,只有特定于WS的代码才属于Web service,而所有实际的业务逻辑属于被Web service方法直接调用的中间层,显然,这十分有用。Visual Studio .NET 2003使用基于代码的方法,而不支持生成传递。

  下面的代码片断显示了声明Web service中的一个Web方法的属性及其选项(示例事务要求),以及声明包含转换启动参数的定制SOAP头的属性。

[WebMethod(TransactionOption=TransactionOption.Required,
BufferResponse=true,
Description="Accepts a standard purchase order form")]
[SoapHeader("startHeader", Direction=SoapHeaderDirection.In)]
public void CreateOrderAsync(purchaseorder data)
{
Workshop传递生成的代码:
/**
* @common:operation
*/
public java.lang.String createOrder(com.beasys.evalguide.PurchaseOrderDocument,
purchaseOrder)
{
return orderEntryService.createOrder(purchaseOrder);
}

可视化设计器:

  Workshop实现异步的Web service转换自有一种功能强大的方式。异步转换的隐喻是扩展为中间层。异步的方法是完全事务化的,带有通过JMS的保证传输(参见createOrderAsync上的队列符号)。.NET需要对事务化的异步行为使用Enterprise Services(COM+) Queued Components(使用MSMQ)。QC不支持回叫(返回路径的第二个QC是必需的,或者QC可以直接调用回叫Web service(我就是使用这种方法))。在.NET中实现这一点仍然很容易,不过没有在WebLogic Workshop中实现起来那么容易。

  Workshop可以使用外部接口到Web service的实际接口这种基于XQuery的映射。BEA称此为松散耦合。此种映射可以以图形化的方式完成。Visual Studio .NET 2003不具备这种功能。

// Visual Studio.NET 2003 convert PO content to internal schema
OrderLinesDataSet lines = new OrderLinesDataSet();
foreach (orderline line in data.orderdata.orderlineitem)
{
lines.OrderLines.AddOrderLinesRow(line.ProductID, "", 0, line.Quantity);
}
// call Queued Component
oes.CreateOrderAsync(startHeader.conversationID, startHeader.callbackLocation,
data.customer.customernumber, lines.GetXml());

  WebLogic支持测试与内置证书的SSL连接。Visual Studio .NET 2003没有这种支持。然而,SSL是一种开发选择,为IIS(Microsoft的Web服务器,用作ASP.NET中Web services的宿主)所完全支持,而且很容易实现(参见讲述详细经验部分中的指导)。两个系统均支持带有签名、加密和策略文件的WS-Security。

  基于WebLogic和.NET的Web services是可完全互操作的。BEA和Microsoft(以及其他公司)已经就互操作性给出了承诺。BEA有一项核心的发行要求,即WebLogic必须通过所有“SOAP-Builders”互操作性测试。

3.6 中间层
  Visual Studio .NET 2003使用完全基于代码的方法,除了数据库访问。我对所有的中间层对象都使用派生自ServicedComponent(Enterprise Services)的组件。这等价于使用标准J2EE中的会话Bean。

  Workshop对中间层组件使用控件(.jcx)。控件是WebLogic中用于所有资源,包括数据库访问、业务逻辑组件、ISV API等的通用隐喻。控件实际上被框架(动态地)封装在适当的bean(会话bean或消息驱动bean)中,就像简单的本地类那样使用。Workshop还自动生成一个接口,并使其保持同步化。这满足了Java对于实际接口的需要,但是不支持接口分解。WebLogic允许显式地定义接口;然而,示例应用程序的架构没有使用这项功能。和所有其他的功能一样,Workshop提供一个可视化的设计器,具有和Web services设计器相同的功能。.NET使用类和接口的方式和WebLogic使用控件的方式完全相同。这包括业务逻辑组件、数据库访问组件、为遗留COM代码自动生成的代理,以及为Web services直接使用的ISV API和自动生成的代理。使用它们就像使用简单的本地类一样。接口是可选的;其过于简化,就像Workshop中自动同步化的接口定义。

  两种系统均使用事务。在ServicedComponent中,程序员可以通过属性控制事务。事务可以使用“AutoComplete”,如果方法的属性指定了它的话。此外,.NET允许程序员控制隔离级别。JCX始终参与事务(框架EJB启动事务)。事务始终使用“AutoComplete”,并使用“可序列化(serializable)”隔离级别。“AutoComplete”在从方法正常返回时提交事务,而且如果抛出异常,则会终止。

//Visual Studio .NET 2003事务属性
[Transaction]
public class OrderEntrySystem : ServicedComponent, IOrderEntrySystem
{ …
[AutoComplete]
string IOrderEntrySystem.CreateOrder(string login, OrderLinesDataSet lines)
{ …

3.7 基于模式的数据
  BEA的产品提供一种称为XML Bean的功能,它已经作为一种开源技术被提交给Apache小组。XML Bean允许Java语法访问基于模式(XSD文件)的实际XML文档。XML文档的完全保真度(包括格式化,比如空格和注释)被XML Bean实现保持了下来,即使当通过XML Bean上的属性存取器修改了元素时也是如此。XML Bean是从XSD架构自动创建的。.NET使用DataSet基于数据处理架构。强类型的DataSet是从XSD文件自动生成的,而且提供对DataSet元素的属性访问。它们比XML Bean具有更多的限制,因为它们是从关系模型演变而来。在ADO.NET DbDataAdapter的帮助下,Dataset可以被读作或写作XML(不用保持原始XML文档的内容),从数据库获得或者保存到数据库。两种产品都包含用于XSD的图形化编辑器。

3.8 富客户端
  Workshop不支持富客户端(Java/Swing)。.NET提供丰富的工具来开发富客户端。.NET支持标准的Windows部署。然而,企业市场的主旨(Holy Grail)是如何为用户提供富客户端的体验,同时维护基于Web的前端的零部署选项。这个“奇迹”是通过.NET非接触部署、代码访问的安全性和通过Web service对后端数据及逻辑的访问而实现的。根据Web serviecs的互操作性,这两种产品可以和WebLogic Web-site和WebLogic Web service一起使用(协作),从而提供富.NET客户端,而不是明显的.NET后端所需的部署和数据。

4. 详细评估
4.1 生产力
4.1.1 代码行和表示数据

  代码行把所有手动输入的行都计算在内,但除开注释、卷曲花括号,或者.NET中加入的但是Workshop评估代码(在源代码中以注释NOT COUNTED标注)中没有的防御性编程。在VB.NET中,end语句(End If、End Class等等)也没有计算在内,因为编辑器将自动插入它们。

  表示的统计包括菜单选取(右击Application/Solution、Add、Project)、使用属性编辑器设置属性、在设计器上放上组件,以及在设计器中绘制行。

  我假定,编写一行代码的时间大约是执行一个表示的两倍。然而,这与个人高度相关。作为一条通用法则,表示需要的技巧/知识较少。

类别 Workshop Visual Studio .NET Workshop Workshop Visual Studio .NET Visual Studio .NET
  投入 投入 步骤 代码行 步骤 代码行
业务逻辑基础 137 162 27 55 20 71
业务逻辑异步 10 69 6 2 11 29
Web应用程序基础 171 89 43 64 21 34
Web应用程序安全性 14 22 2 6 0 11
WS(包括异步) 15 62 5 5 6 28
WS松散耦合 9 14 9 0 2 6
SSL 22 4 0 11 4 0
WS-Security 86 11 2 42 7 2
WS测试 8 135 8 0 23 56
总计 472 568 102 185 94 237

4.1.2 启动时间
  下表显示了在一台CPU为1.6 GHz P4,RAM为512MB的机器上,启动和关机所花费的时间,单位为秒。Workshop明显慢于Visual Studio .NET 2003。当您在内存不足的情况下(例如,打开了多个应用程序时)运行时,这种情况将会更糟。运行Visual Studio .NET 2003以384MB RAM为宜,如果有512MB RAM,就会运行得相当流畅。运行Workshop需要512MB以上的RAM,如果有1GB RAM,性能将达到最佳。

  Workshop VS.NET
启动IDE 40 10
退出IDE 10 1
启动服务器 85 0
停止服务器 15 0
启动调试会话 25 10

4.2 对技术的要求

  Workshop VS.NET 说明
业务逻辑基础 设计独立实现的架构时需要高度的技巧,实现起来所需的技术则较低
业务逻辑异步 设计任何异步组件都需要中等技术。Enterprise Services Queued Components在Visual Studio .NET中首次变得很难
Web应用程序基础 在两个环境中实现Web应用程序都同样简单
Web应用程序安全性 保护任何系统都不是一件技术含量低的工作;然而,这两种环境已经使它变得尽可能的简单
Web services+异步转换 低/中 在两种环境中,实现Web services都是简单的事情;然而,Visual Studio .NET中并不支持直接支持实现异步转换,需要中等技术来手动实现WS-Coordination SOAP头
Web services松散耦合 对于此项,两种环境都只需要较低的技术。这与所采用的完全不同的方法无关
Web services安全性 保护任何系统都不是一件技术含量低的工作;然而,两种环境都已经使其变得尽可能简单

4.3 架构之美
  本节根据作者的认识,从架构“之美”的角度来讨论两种解决方案的相关优点。就像所有审美学方面的评估一样,这是仁者见仁,智者见智的事情。

4.3.1 语言
  通常,我喜欢C#多过Java,因为前者更加清晰,设计更加新颖。C#去掉了对异常声明的需要(给可维护性带来正面的影响),而添加了属性、委派和一个统一类型系统。

4.3.2 架构模式
  WebLogic Workshop和Visual Studio .NET 2003/ASP.NET Web站点遵从良好的架构模式,包括通过分离代码和表示来使Web应用程序中的层变得松散耦合。在这里,二者不分胜负。

  Workshop/WebLogic和Visual Studio .NET 2003/ASP.NET Web services的架构是完善的。我喜欢Visual Studio .NET 2003的基于代码和属性的方法多过图形化方法。我赞同BEA的以下原则,企业级的Web services需要松散耦合的异步通信。我希望Visual Studio .NET 2003提供简单性,把到中间层的传递代码实现为向导或(比Queued Component)更简单的异步事务化组件。WebLogic Workshop在异步企业编程方面占有优势。我不认为基于XQuery的参数映射对生产力的意义重大,因为.NET的基于代码的映射使用极少的代码就能实现。然而,毫无经验的程序员可能更喜欢Workshop的方法。

4.3.3 中间层业务逻辑组件

  对于中间层的开发,我更喜欢与一个更加灵活和透明的框架耦合在一起的.NET代码和Enterprise Service方法。这对技术有着更高的要求,而且会降低编码的效率,但是由此而获得的灵活性足以补偿这一切(这是IDesign的观点)。然而,就像在Web services中一样,WebLogic Workshop有一种非常简单的方式来对企业级异步事务化组件进行编程。WebLogic Workshop生成的代码不为私有成员变量(被控件使用)的显式初始化提供代码。有需要时,框架会魔术般地构造这些。大多数程序员对此觉得很困惑。

4.3.4 使用XML
  对于纯基于XML的数据来说,BEA的XML Bean是更好的解决方案。ADO.NET的强类型DataSet并没有这么灵活。DataSet与RDBMS更好地集成,而且可以直接用于UI数据绑定。这里的胜利者取决于您的使用。如果您的数据是基于XML的,那么显然,XML Bean是胜利者;如果您的数据是在数据库中永久保存,而且以XML的形式进行传输,那么DataSet方法要更好一些,因为WebLogic需要使用XML Bean和RowSet来实现上述功能。

5.详细体验
  本节的目的是描述实现上述两种方法的细节。本节将逐步讲述,而且以截图表示大部分重要的步骤。WebLogic Workshop部分是为Visual Studio .NET程序员编写的,以帮助他们理解该方法,和使用WebLogic Workshop实现一个应用程序的差别。Visual Studio .NET部分是为WebLogic Workshop程序员编写的,以帮助他们理解该方法,和使用Visual Studio .NET实现一个应用程序的差别。

5.1 使用组件
5.1.1 WebLogic实现

  WebLogic需要一个额外的初始化步骤,以创建使用web service或EJB的控件。VS.NET用户应该将此看作显式地生成代理类。
  选择Web Service(或EJB控件),为其指定一个名称(这是代理类的名称):

  接着选择WSDL文件:

  结果:

  生成的源代码:

  现在我们有了代理,让我们使用控件。开始添加一个控件,具体方法是在控件设计器的左侧窗格上右击:

  输入控件的成员变量名称。WebLogic框架将在适当的时候自动实例化这些变量。

  现在,控件或页面流应该是这个样子:

  添加代码以使用组件:

Product[] products = productsSAPSystem.getAllProducts();
curForm = new EnterProductOrderForm(products);

5.1.2 .NET实现
  VS.NET需要为每个所用的部件、web service或COM组件添加一个引用或web引用(对于web services):
常规的.NET或COM组件:

Web Service:

  这就生成了一个到部件的引用。对于web services来说,可以创建一个实际的代理类,然后当您在Solution Explorer中展开Reference节点时,查看该代理类。Solution Explorer中的引用就像下面这样:


下一个步骤是添加下列代码(以黑体表示):

namespace Avitek.OrderEntryService
{

[Transaction]
public class OrderEntrySystem : ServicedComponent, IOrderEntrySystem
{ …
private string EnterOrder(…)
{

IPricingService pricingService = new PricingService.PricingService();

double discountRate = pricingService.GetDiscountRate(custId);

}
}
}

5.2 构建中间层组件
5.2.1 WebLogic实现

  Workshop以图形化的方式设计界面,同时使用逻辑的源代码:

  所使用控件中任何方法(如绿色椭圆区域所示)都可以从数据调色板被拖放到设计器窗格的方法区域,以创建传递代码(如红色箭头所示)。这对于web services最有用,因为web services通常只会调用底层的业务对象方法。然而,这里的UI并没有它应有的直观。更好的UI设计应该允许从图形部分拖放方法(如绿色箭头所示)。调色板是一件多余的复杂事物。另外,还可以拖放表示传递的行。
  点击设计器中的方法可以显示代码视图,您可以在其中加入逻辑:

5.2.2 .NET实现
  VS.NET使用基于代码的方法(除了对数据库访问)。对于ServicedComponent,在没有域控制器的Windows XP中,需要一个后编译事件以避免出现安全异常。在Windows Server 2003中,情况并不是这样。然而,编译指令显式地注册服务组件在任何情况下都是好主意。请注意,该命令是通用的,可以被复制/粘贴到对话框中。



   接下来,部件文件需要下面一行,因为ServicedComponent必须在一个强命名的部件中:
[assembly: AssemblyKeyFile("..\\..\\..\\Assembly.snk")]

  对于服务器激活的组件(Queued Component必须是服务器激活的)来说,您还必须添加:
using System.EnterpriseServices;
[assembly: ApplicationActivation(ActivationOption.Server)]

  如果您编写的是一个Queued Component,请添加:
[assembly: ApplicationQueuing(Enabled = true, QueueListenerEnabled = true)]

  如果您使用的是没有域控制器的Windows XP(例如,您在家或者您是一位独立顾问),请添加:
[assembly: ApplicationAccessControl(false)]

  接下来,您应该添加一个接口(对QC是必需的):

using System;
using System.EnterpriseServices;
namespace Avitek.OrderEntryService.Queued
{
[InterfaceQueuing]
public interface IOrderEntrySystemAsync
{
// queued calls
void CreateOrderAsync(string conversationId, string callbackLocation,
int custId, string serializedDataSet);
}
}

  您可以要求VS.NET给实现类添加实现骨架,具体方法是右击Class View中的接口:

  接下来添加实现代码(下面显示的只是文件的一部分)。注意,Queued Component只可以使用简单的参数(这是一个COM+遗留问题)。所有其他的组件都可以使用复杂的参数。手动添加的代码行以黑体表示:

using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
using Avitek.Commerce.Interface;
using PricingService;
using Sap.Interface;
namespace Avitek.OrderEntryService
{
using TaxCalcService;
/// <summary>
/// Summary description for OrderEntryService.
/// </summary>
///
[Transaction]
public class OrderEntrySystem : ServicedComponent, IOrderEntrySystem
{
public OrderEntrySystem()
{
}
#region IOrderEntrySystem Members
[AutoComplete]
CustomersDataSet IOrderEntrySystem.RetrieveCustomerByLogin(…)
{
IAvitekCommerceSystem commerceApp = new
Avitek.Commerce.AvitekCommerceSystem();
return commerceApp.RetrieveCustomerByLogin(loginName);
}


5.3 构建Web Services
5.3.1基本的Web Services
5.3.1.1 WebLogic实现

  在WebLogic中,Web Services是特殊的控件(jws):



  接下来,添加任何所需的组件(orderEntryService),然后通过从数据调色板拖放的方法来添加传递代码:

  Workshop有一种十分有效的方式用于实现异步的web service转换。异步转换的隐喻扩展为中间层。只要选择属性(下图表现出了它们)即可:

  Workshop可以使用外部接口到Web service的实际接口这种基于XQuery的映射。BEA称此为松散耦合。此种映射可以以图形化的方式完成:

5.3.1.2 .NET实现
  Web Services以ASP.NET为宿主,通过添加一个新项目给解决方案来创建:

  余下的部分是通过编程完成的(包括异步和转换支持)。我使用XSD命令行工具把虚构的行业协会提供的外部PurchaseOrderDoc.xsd转换为类定义。我加入了web service OrderWebService.asmx的实际实现(手动添加的代码以黑体表示):

using System.Runtime.InteropServices;
using System.EnterpriseServices;
using System.IO;
using Avitek.OrderEntryService;
using Avitek.OrderEntryService.Queued;
namespace AvitekOrderEntryWS
{
/// <summary>
/// Summary description for OrderWebService.
/// </summary>
public class OrderWebService : System.Web.Services.WebService
{
public OrderWebService()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
// initialize queue
OrderEntrySystemAsync obj = new OrderEntrySystemAsync();
ServicedComponent.DisposeObject(obj);
}
#region Component Designer generated code
//Required by the Web Services Designer
private IContainer components = null;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
public StartHeader startHeader;
[WebMethod(
TransactionOption=TransactionOption.Required,
BufferResponse=true,
Description="Accepts a standard purchase order form")]
[SoapHeader("startHeader", Direction=SoapHeaderDirection.In)]
{
Avitek.OrderEntryService.Queued.IOrderEntrySystemAsync oes;
// convert PO content to internal schema
OrderLinesDataSet lines = new OrderLinesDataSet();
foreach (orderline line in data.orderdata.orderlineitem)
{
lines.OrderLines.AddOrderLinesRow(line.ProductID, "", 0,
line.Quantity);
}
// invoke order entry system through queued component
oes = (IOrderEntrySystemAsync)Marshal.BindToMoniker(
"queue:/new:Avitek.OrderEntryService.Queued.OrderEntrySystem");
try
{
// real call
startHeader.DidUnderstand = true;
oes.CreateOrderAsync(startHeader.conversationID,
startHeader.callbackLocation, data.customer.customernumber,
lines.GetXml());
}
finally
{
// actually commit the send by disposing the proxy
int refCount = Marshal.ReleaseComObject(oes);
}
}
}
[XmlTypeAttribute(Namespace="http://www.openuri.org/2002/04/soap/conversation/")]
[XmlRootAttribute(Namespace="http://www.openuri.org/2002/04/soap/conversation/",
IsNullable=false)]
public class StartHeader : SoapHeader
{
public string conversationID;
public string callbackLocation;
}
}

5.3.2 SSL
5.3.2.1 WebLogic实现

  把下面的代码行添加到web.xml中 :

<web-resource-collection>
<web-resource-name>OrderEntryWebService.jws</web-resource-name>
<url-pattern>
/webServices/orderEntryInterface/OrderEntryWebService.jws/*
</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
在wlw-config.xml文件中添加以下内容:
<service>
<class-name>webServices.orderEntryInterface.OrderEntryWebService</class-name>
<protocol>https</protocol>
</service>

5.3.2.2 .NET实现
  首先,您在IIS MMC插件中设置https的虚拟目录(右击并选择Property):



   我没有有效的服务器证书(参见上面对话框中灰色的选项),所以无法完成此项工作。
然后,您需要在您的测试项目中修改web引用URL,以读取https://localhost/.......

5.3.3 WS-Secrutiy
5.3.3.1 WebLogic实现


Workshop/WebLogic需要使用XML手动编辑两个策略文件:
wsSecurityPolicy xsi:schemaLocation="WSSecurity-policy.xsd"
xmlns="http://www.bea.com/2003/03/wsse/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<wsSecurityOut>
<signatureKey>
<alias>client1</alias>
<password>password</password>
</signatureKey>
<!--
The signatureKey tag above specifies that the outgoing SOAP
message is to be signed with the sender's private key.
Only the sender's public key can validate the signature.
This ensures the authenticity of the sender, i.e., that the
sender is in fact the actual source of the SOAP message.
-->
</wsSecurityOut>
<wsSecurityIn>
<signatureRequired>true</signatureRequired>
<!--
The signatureRequired tag above indicates that incoming
SOAP messages must be digitally signed with the sender's
private key. The sender's public key is used to validate
the signature.
-->
</wsSecurityIn>
<keyStore>
<keyStoreLocation>samples_client.jks</keyStoreLocation>
<keyStorePassword>password</keyStorePassword>
</keyStore>
<!--
The keyStore tag indicates the keystore to be used is samples_client.jks.
The keystore is indicated to be in the default location, the server
domain root, which in this case is
BEA_HOME\weblogic81\samples\domains\workshop.
-->
</wsSecurityPolicy>
and:
<?xml version="1.0" ?>
<wsSecurityPolicy xsi:schemaLocation="WSSecurity-policy.xsd"
xmlns="http://www.bea.com/2003/03/wsse/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<wsSecurityIn>
<signatureRequired>true</signatureRequired>
<!--
The signatureRequired tag above specifies that incoming
SOAP messages must be digitally signed with the sender's
private key. The sender's public key is used to validate
the signature.
-->
</wsSecurityIn>
<wsSecurityOut>
<signatureKey>
<alias>mycompany</alias>
<password>password</password>
</signatureKey>
<!--
The signatureKey tag above specifies that the outgoing SOAP
message is to be signed with the sender's private key.
Only the sender's public key can validate the signature.
This ensures the authenticity of the sender, i.e., that the
sender is in fact the actual source of the SOAP message.
-->
</wsSecurityOut>
<keyStore>
<keyStoreLocation>samples_mycompany.jks</keyStoreLocation>
<keyStorePassword>password</keyStorePassword>
</keyStore>
<!--
The keyStore tag indicates the keystore to be used is samples_mycompany.jks.
The keystore is indicated to be in the default location, the server
domain root, which in this case is
BEA_HOME\weblogic81\samples\domains\workshop.
-->
</wsSecurityPolicy>

  余下的部分全通过两个属性完成:

  接下来,需要构建一个测试客户端,因为这是Workshop不能动态创建的惟一测试客户端。为web service创建一个控件(代理)(选择一次菜单就可以构建它),然后在属性窗格中设置WS-Security策略。

  使用一次简单的传递创建使用实际web service的测试web service:

5.3.3.2 .NET实现
  下载WSE 2.0(预览版)。给WS和测试客户端都添加一个到Microsoft.web.services.dll 2.0的AvitekOrderEntryWS的引用:

  使用WSE Configuration管理器来编辑WS中的Web.config和测试客户端中的app.config,如下所示:





  为测试客户端和web service添加一个安全性策略:


  WSE 2.0的预览版(用于这个项目)在用于添加实际的SOAP扩展的配置工具中有一个bug(第一个选项卡中的复选框被禁用)。您必须在Web.config文件中加入以黑体突出显示的部分:

<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
<webServices>
<soapExtensionTypes>
<add type="Microsoft.Web.Services.WebServicesExtension,
Microsoft.Web.Services, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>

  添加给web services文件和测试客户端源代码:

using Microsoft.Web.Services;

  在测试客户端中添加代码,以查找证书,并将其放入策略的全局缓存中以装载它:

using Microsoft.Web.Services.Security;
using Microsoft.Web.Services.Security.X509;

// Generate the x.509 security token
X509SecurityToken token = GetSigningToken();
if (token == null)
throw new ApplicationException(
"Unable to obtain security token.");
SecurityTokenCache.GlobalCache.Add(token);
//execute call
ws.CreateOrderAsync(order);
}
private X509SecurityToken GetSigningToken()
{
// Replace the key id below with your own certificate Id
string ClientBase64KeyId = "gBfo0147lM6cKnTbbMSuMVvmFY4=";
X509SecurityToken token = null;
X509CertificateStore store = null;
// Open the CurrentUser Certificate Store
store = X509CertificateStore.CurrentUserStore(
X509CertificateStore.MyStore);
if (store.OpenRead())
{
// Place the key ID of the certificate in a byte array
X509CertificateCollection certs =
store.FindCertificateByKeyIdentifier(
Convert.FromBase64String(ClientBase64KeyId));
if (certs.Count > 0)
{
// Get the first certificate in the collection
token = new X509SecurityToken((X509Certificate)certs[0]);
}
store.Close();
}
return token;
}

  修改在客户端上生成的代理(在Reference.cs中),以从Microsoft.Web.Services.WebServicesClientProtocol派生。
  检查WS中的SOAP正确性:

public void CreateOrderAsync(purchaseorder data)
{
// Reject any requests which are not valid SOAP requests
if (RequestSoapContext.Current == null)
throw new ApplicationException(
"Only SOAP requests are permitted.");

5.4 构建Web应用程序
5.4.1 设计页面
5.4.1.1 WebLogic实现

  WebLogic使用一个图形化的页面流模型来设计web站点。每个流文件(*.jpf)是web站点的或一个部分(流可以嵌套)的控制器的可视化描述。节点是页面和由用户动作引起的动作。箭头表明要执行的下一项:

  双击页面节点(.jsp)可以打开单独的页面设计器:

  流(.jpf)的动作视图显示了类似的控件设计器窗格。流只不过是带有另外元素(比如流定义)的另一种控件:

  最后,Source View显示了对动作作出反应的实际源代码:

  我们还需要一个FormBean:

5.4.1.2 .NET实现
  我在VB.NET中实现了web站点。VB.NET和C#通常可以互相交换。
VS.NET使用一个图形化的设计器进行页面设计。构建块是预构建的控件、用户控件(下面的Header)、第三方控件(下面的来自Infragistics的网格)和数据元素(下面位于米色区域中的m_OrderLines强类型DataSet):

  双击一个按钮(Submit Order),可以为页面的隐藏代码文件中的动作创建处理器。隐藏代码还包含在页面装载期间完成的动作。下面的”NOT COUNTED”注释标志了防御性编程行(如果ASP.NET正确运行身份验证和数据验证,用于不可能的情况):

Imports System.Security
Imports Avitek.OrderEntryService
Public Class OrderEntry
Inherits System.Web.UI.Page
Protected m_OrderEntrySystem As IOrderEntrySystem
Protected m_OrderLines As OrderLinesDataSet
Protected WithEvents OrderGrid As Infragistics.WebUI.UltraWebGrid.UltraWebGrid
Protected WithEvents NonZeroLinesCustomValidator As _
System.Web.UI.WebControls.CustomValidator
Protected WithEvents ValidationSummary As _
System.Web.UI.WebControls.ValidationSummary
Protected WithEvents SubmitButton As System.Web.UI.WebControls.Button
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.m_OrderLines = New Avitek.OrderEntryService.OrderLinesDataSet
CType(Me.m_OrderLines, _
System.ComponentModel.ISupportInitialize).BeginInit()
'
'm_OrderLines
'
Me.m_OrderLines.DataSetName = "OrderLinesDataSet"
Me.m_OrderLines.Locale = New System.Globalization.CultureInfo("en-US")
CType(Me.m_OrderLines, System.ComponentModel.ISupportInitialize).EndInit()
End Sub
'NOTE: The following placeholder declaration is required by the Web Form
‘ Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
m_OrderEntrySystem = New Avitek.OrderEntryService.OrderEntrySystem
If IsPostBack Then
'
Else
m_OrderLines = m_OrderEntrySystem.RetrieveAllProducts()
DataBind()
End If
End Sub
Private Sub SubmitButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles SubmitButton.Click
If IsValid And User.Identity.IsAuthenticated Then 'NOT COUNTED
m_OrderLines.Clear()
Dim numLines As Integer = 0
For i As Integer = 0 To OrderGrid.Rows.Count - 1
Dim gridRow As Infragistics.WebUI.UltraWebGrid.UltraGridRow = _
OrderGrid.Rows(i)
Dim quantity As Integer = gridRow.Cells(3).Value
If quantity > 0 Then
m_OrderLines.OrderLines.AddOrderLinesRow( _
gridRow.Cells(0).Value, "", 0, quantity)
numLines += 1
End If
Next
If numLines > 0 Then 'NOT COUNTED
Dim orderEntrySystem As IOrderEntrySystem = New OrderEntrySystem
Dim result As String = _
orderEntrySystem.CreateOrder(User.Identity.Name, m_OrderLines)
Context.Items("OrderResult") = result
Server.Transfer("OrderResults.aspx")
Else 'NOT COUNTED
Throw New ApplicationException( _
"Validation did not work correctly")
End If
Else 'NOT COUNTED
'should not happen
Throw New SecurityException( _
"Attempt to circumvent security system detected")
End If
End Sub

5.4.2 修改流
5.4.2.1 WebLogic实现

  Workshop允许对流进行修改,具体方法是在流设计器中把箭头从一个位置移动到另一个位置。

5.4.2.2 .NET实现
  .NET需要修改动作处理器末尾处的一行代码(例如:修改index.html以指向Greeting.aspx):

5.4.3 数据绑定和验证
5.4.3.1 WebLogic实现


Workshop/WebLogic需要添加数据绑定标签给Repeater和repeater项中的每一栏(4×):
<data:repeater dataSource="{actionForm.productOrders}">
<netui:label value="{container.item.product.productID}"/>
Workshop/WebLogic要求FormBean中的代码实现数据验证:

  接下来,我们把enterProductOrder动作的验证错误页面设置为OrderDetails.jsp:

  现在,我们添加Errors控件(这将显示从上面的验证代码返回的ActionErrors列表):

5.4.3.2 .NET实现
.NET使用一个属性来设置数据绑定(最适用于强类型的Dataset):

  另外,无论您在哪里加载了DataSet(通常是在隐藏代码文件的Page_Load中),您必须添加一行代码,用于调用System.Web.UI.Page中的DataBind:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
m_OrderEntrySystem = New Avitek.OrderEntryService.OrderEntrySystem
If IsPostBack Then
'
Else
m_OrderLines = m_OrderEntrySystem.RetrieveAllProducts()
DataBind()
End If
End Sub

  为了提供定制的验证,所以插入了一个定制的验证器控件。.NET也有几个预定义的验证器。因为这是页面上惟一的验证器,我决定始终隐藏它(属性)。我还加入了一个归纳错误的显示控件。双击定制的数据验证器,可以创建用于添加实际验证代码的验证处理器。ASP.NET负责处理余下的工作。我能够使这项工作变得更加简单,而且只使用验证器;然而,如果我想要添加另外的验证代码,这将无法进行扩展:

Protected Sub NonZeroLinesCustomValidator_ServerValidate(ByVal source As _
System.Object, ByVal args As _
System.Web.UI.WebControls.ServerValidateEventArgs) Handles _
NonZeroLinesCustomValidator.ServerValidate
Dim numLines As Integer = 0
For i As Integer = 0 To OrderGrid.Rows.Count - 1
Dim quantity As Integer = OrderGrid.Rows(i).Cells(3).Value
If quantity > 0 Then
numLines += 1
End If
Next
args.IsValid = numLines > 0
End Sub

5.4.4 表单身份验证和授权

  本节要求已经使用任何所需的基础架构开发了Login、Regitration页面(或页面流),以访问证书数据库。

5.4.4.1 WebLogic实现
  从创建角色AvitekCustomer开始。在Application窗口中,右击“Security Roles”节点(位于目录结构的底部),然后选择“Create new role…”:

  接下来,修改OrderEntryController页面流的属性RolesAlowed,以应用新的AvitekCustomer角色。

  因为基础架构的余下部分是预构建的,配置已经完成。现在,开始添加用于在订单流程中使用来自身份验证的用户信息的代码。必须将begin动作修改为下面这样(4行):

  必须将enterProductOrderAction修改为下面这样(1行:”int custID = …”):

5.4.4.2 .NET实现
  从修改Web.config文件开始(修改的地方以黑体表示):

<authentication mode="Forms">
<forms loginUrl="Login.aspx" timeout="30" />
</authentication>
<authorization>
<deny users="?" />
<allow roles="AvitekCustomer" />
<!-- <allow users="[comma separated list of users]"
roles="[comma separated list of roles]"/>
<deny users="[comma separated list of users]"
roles="[comma separated list of roles]"/>
-->
</authorization>
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
</system.web>
<location path="Index.aspx">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
<location path="Registration.aspx">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
</configuration>

  因为我前面把.NET设计建立在传递登录名给中间层的基础之上,所以不需要为此修改代码,除了传递登录名而不是硬编码的名称john之外:

result = orderEntrySystem.CreateOrder(User.Identity.Name, m_OrderLines)

6. 关于作者
  IDesign是一家行业领先的.NET架构咨询和培训公司。IDesign组织在软件开发行业中有着很深的积累和沉淀。IDesign组织在大型公司中,在技术和管理的最前沿,占据了很多高级职位。这些职位包括VP Engineering、首席信息官、工程总监、公司架构经理、首席架构师和开发经理。他们撰写了很多行业领先的书籍,并经常出席贸易展。
  Heinrich Gantenbein是IDesign在Java到.NET的迁移以及ADO.NET方面的专家。凭借这个身份,Heinrich帮助当前正在使用Java和J2EE的客户理解了什么是.NET,如何利用.NET来使他们的业务受益,以及如何设计多层分布式数据访问应用程序。他还参与Microsoft的Preview Labs,就未来的.NET技术回复问题。他在软件工程和工程管理领域中拥有18年以上的经验,能够把架构优点和承诺结合为一个高效率的开发流程。Heinrich在Silicon Valley Group,KLA-Tencor,IBM的合资MAS担任高级职位,因此,他始终了解和熟悉最新的尖端技术。以前,Heinrich是Excite@Home的工程总监,负责管理开发面向国内和国际市场的多层应用程序的大型团队。

6.1 关于BEA
  BEA系统有限公司(Nasdaq:BEAS)是全球领先的应用基础件(Application Infrastructure)公司,为全球 15,000余家客户提供企业软件基础,其中包括《财富》全球500强公司中的大部分公司。BEA及其WebLogic™、Tuxedo™品牌是业界最值得信赖的品牌。

7. 术语

使用 WebLogic Workshop 8.1和J2EE Visual Studio .NET 2003和.NET Framework
语言 Java C#、VB.NET和其他
本地组件 控件(jcx) 类、接口
企业组件 控件(jcx)或EJB会话Bean ServicedComponent(EnterpriseServices)派生的类
数据访问 数据库控件(jcx)或EJB实体Bean ADO.NET、DataAdapter、强类型DataSet
队列处理 JMS,控件中支持以简化JMS使用 Queued Component(Enterprise Services)
模式定义的数据结构 Schema文件和XML Bean 强类型的DataSet,或架构(使用工具xsd.exe)生成的对象
基本的语言和框架 J2SE C#、VB.NET、.NET Framework、CLR
企业框架 J2EE Enterprise Services,、ASP.NET、 ADO.NET
在Web页面中把表示和动作处理分离 Java页面流 ASP.NET隐藏代码
Web页面定义 JSP ASP.NET .asmx
使用Web service Web service控件(自动生成) Web引用=Web service代理(自动生成)

 

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有