WebLogic Server 技术白皮书

gqlpen

贡献于2012-05-31

字数:0 关键词: 应用服务器 WebLogic

1 目 录 第 1 章 WebLogic 介绍 ................................................................................................6 1.1 BEA WebLogic Server 是什么?.....................................................................6 1.2 WebLogic Server 概述......................................................................................6 第 2 章 J2EE 体系介绍 ..............................................................................................11 2.1 J2EE 简介 .......................................................................................................11 2.2 J2EE 体系结构概览 .......................................................................................12 2.3 J2EE 的优势所在 ...........................................................................................13 2.4 J2EE 的规范组成 ...........................................................................................13 2.5 显示逻辑.........................................................................................................14 2.5.1 Java Servlets............................................................................................14 2.5.2 Java 服务器页面(JSP).................................................................15 2.5.3 JavaBeans 和标记(Tag)库.................................................................16 2.6 数据库和事务支持.........................................................................................16 2.6.1 Java 数据库连接(JDBC)...................................................................16 2.6.2 Java 事务 API(JTA)/Java 事务服务(JTS) ...................................17 2.6.3 对象注册和远程方法调用(RMI).............................................18 2.6.4 Java 命名和目录接口(JNDI) ............................................................19 2.6.5 远程方法调用(RMI) .........................................................................19 2.7 企业级 Java 组件(EJB) .............................................................................19 2.7.1 实体 EJB (Entity EJB)......................................................................20 2.7.2 会话 EJB(Session EJB) ...............................................................21 2.7.3 消息驱动 Bean(Message Driven Bean)...................................21 2.8 Java 消息服务(JMS) .................................................................................22 2.9 Java 接口定义语言(IDL) ...............................................................................22 2.10 JavaMail ..........................................................................................................22 2.11 安全.................................................................................................................23 2.12 J2EE 客户端 ...................................................................................................23 第 3 章 表示层应用构建.............................................................................................24 3.1 表示层技术实现.............................................................................................25 3.2 Servlet .............................................................................................................27 3.2.1 Servlet 概念 ............................................................................................27 3.2.2 JSP 技术...............................................................................................30 3.2.3 使用 Taglib 和自定制的标记.................................................................34 3.3 Web Service 的应用 .......................................................................................50 3.4 个性化设计.....................................................................................................59 3.5 表示层应用设计模式.....................................................................................66 第 4 章 EJB 构建业务逻辑层 ....................................................................................75 4.1 EJB 的体系结构 ............................................................................................76 4.1.1 N 层网络结构......................................................................................76 4.1.2 关于组件的讨论.................................................................................79 4.1.3 EJB 的分类 ..........................................................................................81 4.1.4 客户端对 EJB 的调用.......................................................................87 2 4.2 WebLogic Sever 的 EJB 容器 .......................................................................92 4.2.1 实体 Bean 的 ejbLoad()和 ejbStore() .........................................101 4.2.2 把实体 Bean 设成 Read-Only(只读) ..............................................104 4.2.3 只读 EJB 的限制 .................................................................................106 4.2.4 主读(Read-Mostly)..........................................................................106 4.3 WebLogic Server 集群中的 EJB..................................................................107 4.3.1 在集群中的 EJB 对象 .........................................................................108 4.3.2 在集群中的 EJB 对象 .........................................................................109 4.3.3 集群中的无状态会话 Bean..................................................................109 4.3.4 集群中的有状态会话 Bean.................................................................111 4.3.5 集群中的实体 Bean.............................................................................113 4.4 实体 Bean 的锁服务(Locking Service) .................................................114 4.4.1 排他锁服务(Exclusive locking services) ........................................114 4.4.2 数据库锁服务.......................................................................................115 4.4.3 设置数据库锁.......................................................................................115 4.5 EJB 的环境,安全,资源和事务 .....................................................................116 4.5.1 环境(Environment).....................................................................116 4.5.2 资源(Resource)............................................................................117 4.5.3 安全(Security) .............................................................................120 4.5.4 EJB 之间的互相调用 ......................................................................126 4.5.5 EJB 的事务 ........................................................................................128 4.6 EJB 系统设计的考虑 ...................................................................................137 4.6.1 在 WebLogic Server 上使用 EJB 的考虑...................................140 4.6.2 远程对象.............................................................................................142 4.6.3 继承......................................................................................................142 4.6.4 引用.......................................................................................................143 4.6.5 生命周期...............................................................................................144 4.6.6 事务......................................................................................................144 4.6.7 持久性.................................................................................................146 4.6.8 资源......................................................................................................146 4.6.9 EJB QL................................................................................................147 4.6.10 CMP.....................................................................................................147 4.6.11 消息驱动 Bean.........................................................................148 4.6.12 4Session Bean....................................................................................148 4.6.13 实体 Bean..................................................................................151 4.6.14 消息驱动 Bean.........................................................................167 4.6.15 C/S 接口..............................................................................................168 4.6.16 对 EJB 服务的访问..................................................................168 4.6.17 EJB 服务的粒度(granularity) ..................................................168 4.7 一个具体用例...............................................................................................169 4.8 总结...............................................................................................................185 第 5 章 Weblogic JDBC ...........................................................................................185 5.1 JDBC 简介....................................................................................................186 3 5.2 一个简单的例子...........................................................................................188 5.3 JDBC 编程....................................................................................................190 5.3.1 JDBC 主要接口和类简介..............................................................190 5.3.2 驱动程序.............................................................................................191 5.4 例子执行与分析...........................................................................................198 5.4.1 执行程序.............................................................................................198 5.4.2 代码分析.............................................................................................199 5.5 WEBLOGIC 中的 JDBC 处理....................................................................204 5.5.1 在 Weblogic 中使用 JDBC 驱动程序.......................................204 5.5.2 Weblogic 连接池 ..............................................................................205 5.5.3 Weblogic 数据源(Data Source)...............................................209 5.5.4 weblogic 多池管理(Multipool)技术 ......................................212 5.6 分布式事务处理...........................................................................................213 5.6.1 分布式事务处理(Distributed Transaction Processing,DTP) 213 5.6.2 JAVA 中的分布式事务支持。 ....................................................215 5.7 WEBLOGIC 中的事务处理.........................................................................220 5.7.1 一个 JTA 样例 .................................................................................220 5.7.2 weblogic 的事务控制。 ................................................................226 5.8 实践经验.......................................................................................................227 第 6 章 J2EE 的一些专题讨论 ...............................................................................229 6.1 JCA................................................................................................................229 6.1.1 WebLogic J2EE 连接器体系结构概述......................................229 6.1.2 基于 J2EE 1.2 和 1.3 的 WebLogic 6.1 服务器基础.............229 6.1.3 J2EE 连接器体系结构术语..........................................................229 6.1.4 BEA WebLogic J2EE 连接器体系结构实现概述 ..................230 6.1.5 黑盒实例.............................................................................................232 6.1.6 安全管理.............................................................................................232 6.1.7 容器管理的签名和应用管理的签名...........................................232 6.1.8 安全角色映射 ...................................................................................233 6.1.9 口令转换工具 ...................................................................................233 6.1.10 事务管理.....................................................................................233 6.1.11 支持的事务级别.......................................................................233 6.1.12 .rar 配置文件定义事务级别..........................................................234 6.1.13 事务管理协议 ...........................................................................234 6.1.14 连接管理.....................................................................................234 6.1.15 错误日志和跟踪工具..............................................................234 6.1.16 配置连接属性 ...........................................................................234 6.1.17 BEA WebLogic 服务器扩展的连接管理属性 ........................235 6.1.18 监控连接池................................................................................235 6.1.19 配置..............................................................................................235 6.1.20 资源适配器开发工具..............................................................236 6.1.21 配置资源适配器.......................................................................236 4 6.1.22 配置 weblogic-ra.xml 文件 ....................................................238 6.1.23 使用口令转换工具 ..................................................................239 6.1.24 配置事务类型 ...........................................................................239 6.1.25 开发 J2EE 连接器体系结构的资源适配器.......................239 6.1.26 连接管理.....................................................................................239 6.1.27 安全管理.....................................................................................240 6.1.28 事务管理.....................................................................................240 6.1.29 打包..............................................................................................240 6.1.30 资源适配器部署.......................................................................240 6.2 XML..............................................................................................................245 6.3 Weblogic Server JMS....................................................................................260 6.4 Weblogic Server 的安全性...........................................................................273 第 7 章 WLS 高级功能.............................................................................................286 7.1 WebLogic Server 集群.................................................................................286 7.1.1 WebLogic Server 集群概貌..........................................................286 7.1.2 什么是 WebLogic Server 集群 ....................................................286 7.1.3 在 WebLogic Server6.0 上集群新特征.......................................288 7.1.4 什么服务可以做集群...............................................................288 7.1.5 WebLogic Server 集群配置结构...............................................289 7.1.6 WebLogic Server 集群通信机制.................................................290 7.1.7 WebLogic Server 集群的基本体系结构 ...................................294 7.1.8 WebLogic Server 集群的多层体系结构 ...................................294 7.1.9 WebLogic Server 集群的配置步骤 ............................................296 7.2 WebLogic TUXEDO 连接器(WTC)......................................................297 7.2.1 简介......................................................................................................297 7.2.2 WTC 安装与配置.............................................................................298 7.3 WebLogic Server 性能调优..........................................................................306 7.3.1 概述......................................................................................................306 7.3.2 硬件......................................................................................................306 7.3.3 操作系统.............................................................................................307 7.3.4 Java 虚拟机........................................................................................307 7.3.5 WebLogic 应用服务器....................................................................308 7.3.6 J2EE 的服务 ......................................................................................310 7.3.7 应用......................................................................................................313 7.3.8 小结......................................................................................................313 7.4 与其它系统的集成—WLI ...........................................................................313 7.4.1 WLI 简介............................................................................................313 7.4.2 BEA WebLogic Integration ............................................................317 7.4.3 应用服务器........................................................................................320 7.4.4 应用集成.............................................................................................324 7.4.5 业务流程管理 ...................................................................................330 7.4.6 B2B 集成 ............................................................................................334 7.4.7 结论......................................................................................................339 5 6 第1章 WebLogic 介绍 本章对于 BEA WebLogic Server 作一个提纲挈领的介绍,详细的介绍请参见后面的有关 章节。 1.1 BEA WebLogic Server 是什么? BEA WebLogic Server 是一个支持企业级的、多层的、完全分布式的 Web 应用的 Java 应用服务器。WebLogic Server 在开发和部署 Java 电子商务类应用领域无可争议地作为市场 的领导者以其事实上的标准而在业界享有盛名。 1.1.1.1 BEA WebLogic Server: 为包括 Web 浏览器、applets 和应用客户等各种类型客户端维护和管理应用逻辑和业务 规则。 对运行于 WebLogic Server 之上的 Web 和企业级 Java 组件(EJB)服务提供软件集群 (clustering),从而确保可靠性、可伸缩性和高性能。 提供必要的应用服务,来创建强健的、可伸缩的、基于 Web 方式的应用。 提供了 Sun J2EE (Java 2 平台企业版) 规范的最新并且完整的实现。 通过强调最有效利用客户与数据库连接等系统资源,BEA WebLogic Server 因而能够支 持面向数百万用户和每小时数十万个请求的电子商务应用。 1.2 WebLogic Server 概述 图 1-1 显示的是一个典型的多层 WebLogic Server 配置。客户端包括 Web 浏览器和应用 客户端。其中的 WebLogic Server 层通常为一组 WebLogic Server 相互协作而成的集群 (cluster)。 7 Web 浏览器 Web 浏览器 应用 客户端 应用 客户端 互联网 WebLogicWebLogic WebLogicWebLogic WebLogicWebLogic 数据库数据库 第一层 客户端 第一层 客户端 第二层 应用服务器 第二层 应用服务器 第一层 数据库或后端应用 第一层 数据库或后端应用 图1-1: 典型的WebLogic Server 配置 图 1-1 中的六角形表示 WebLogic Server 容器(container),其中包含着一系列的服务和 工具。 1.2.1.1 容器组件模型(Container-Component Model) WebLogic Server 平台可以被形容为一个容器(container),提供用户应用中的组件所需 要的服务。诸如 EJB、JSP 和 servlet 之类的组件驻留在 WebLogic Server 容器之上,并且利 用它所提供的服务。 在图 1-2 中,WebLogic Server 容器(大五角形)封装了各种各样的 J2EE 服务。服务之 间的连接以线和箭头进行描述。WebLogic Server 管理(通过 WebLogic Server 控制台)和安 全作为容器之外的层次来显示。 8 Web 客户端 Web 客户端 数据库数据库 图1-2: WebLogic Server 容器的结构一览 JNDIJNDI Mail系统Mail系统 JavaMailJavaMail EJBEJB JDBCJDBC JMSJMS 管理管理 安全安全 JSP Servlet JSP Servlet 1.2.1.2 WebLogic Server 的优势在于:组件支持和可伸缩性 WebLogic Server 中的作为 J2EE 服务器端编程战略中心-EJB 的实现,是大多数企业级 Web 应用的心脏所在。EJB 集成了数据管理、会话管理与业务逻辑,并且在应用中所有层之 间进行协调。比如,您采用实体 bean (entity bean)来代表从数据库中的数据;您采用会话 bean (session bean)来实现业务逻辑,它们要么太复杂要么过于敏感而不便于交给显示逻辑去管 理;再者,您还可使用消息驱动 bean(MDB)来建立异步的数据处理。 在 WebLogic Server 容器内部,组件用来提供连接和通讯服务,多用户操作时的事务支 持,以及能够通过复制或集群来提供更好的性能与可伸缩性。 对于容器和组件框架,WebLogic Server 增加了几种重要的集群机制来确保分布式应用 的高可用性和伸缩性。一个 BEA WebLogic Server 集群为一组 WebLogic Server,通过协调 它们的动作,使用透明的方式来提供可伸缩的、高可用的服务。集群中的 WebLogic Server 可以运行在异构的硬件和软件平台上:此时它们之间可以通过基于 Java,平台独立 API 来 进行互操作。 WebLogic Server 集群技术对于 Web 页面创建(显示逻辑)和 EJB 组件(业务逻辑), 都可以透明支持复制、负载均衡和故障恢复等。 9 图1-3: 集群 1.2.1.3 WebLogic Server 作为应用服务器所提供的平台软件功能 表示服务方面: WebLogic Server 提供以下功能: 内置 Web 服务器 Apache、Microsoft IIS 与 Netscape 集成 Servlet 与 JSP 引擎 高级 Web 高速缓存 作为一个自含式平台,可服务无线和 Web 应用的静态和动态内容,它利用高速页面缓 存提高性能和可伸缩性。 企业级消息处理平台方面: WebLogic Server 提供以下两种不同形式的功能: 群集的 JMS JavaMail 集成的消息处理为企业内业务数据和事件的异步交换提供了可靠、灵活的服务。企业级 消息处理平台可处理点对点或发布/订阅体系结构的高伸缩性消息生成和处理。 企业管理: 基于 Web 的管理控制台 Java 管理扩展(JMX) SNMP 10 WebLogic Server 可以为开发人员和管理员提供基于 Web 的配置和监测工具,或与领先 的管理机制集成。 安全性: WebLogic Server 提供以下几种手段: 灵活验证和授权 完善的安全和防火墙支持 完善的日志记录 WebLogic Server 采用基于 SSL、X.509 数字证书和 ACL 等的可选加密、验证和授权, 而保证联网应用系统的安全。所有 WebLogic Server 服务均可通过 HTTP 或 HTTPS 管道 和通过防火墙而可靠地获得。 XML 与 Web Services: WebLogic Server 完全支持 XML 及 Web Services 领域中的几项标准: SOAP WSDL UDDI WebLogic Server 的开发人员无需额外编程,就可把 EJB 转为 Web Services,或远程访 问其它平台上的 Web Services。 应用集成方面: WebLogic Server 提供对 J2EE Connector Architecture(连接体系结构,简称 J2EE CA) 的支持。J2EE CA 支持可让所有应用系统凭借符合 J2EE CA 的资源适配器“插入”WebLogic Server。建 立 于 BEA WebLogic Server 之上的 BEA WebLogic Integration™具有企业应用集成 领域所需要的高级集成功能。 11 第2章 J2EE 体系介绍 本章介绍 J2EE 的概念,规范组成及每一规范的用途所在。 Sun 公司的 J2EE 框架是在 1997 年度 Java One 大会上发布的。J2EE 定义了开发和部署 企业级 Web 应用的标准。通过 J2EE,Java 语言与工具得以延伸到那些复杂的、多层的电子 商务和企业级应用当中。J2EE 对于组件模型的开发提供广泛的支持,且对以模块化、可重 用、平台独立组件的方式构建业务逻辑方面提供相应的工具与服务。 2.1 J2EE 简介 J2EE 是针对 Web 服务、业务对象、数据访问和消息传送的一组规范。这组应用编程接 口(API)确定了 Web 应用与驻留它们的服务器之间的通信方式。J2EE 注重两件事:一是 建立标准,使 Web 应用的部署与服务器无关;二是使服务器能控制组件的生命周期和其它 资源,以便能够处理扩展、并发、事务处理管理和安全性等问题。 J2EE 平台为设计、开发、安装和部署企业应用提供基于组件的方法。这种方法不但能 降低成本,还能快速跟踪设计和实施。J2EE 平台能提供多层分布式应用模型,重复利用组 件,提供统一安全模式,并灵活地控制事务处理。借助 J2EE,不但能更快地将客户解决方 案推向市场,还能使基于 J2EE 组件、不依赖于平台的解决方案不被锁定到任何厂商的产品 和 API 上。 J2EE 规范定义了以下几种组件: 应用客户端组件 Enterprise JavaBeans 组件 Servlets 和 Java Server Pages(JSP) 组件(也称为 Web 组件) 小应用程序 (Applet) 12 2.2 J2EE 体系结构概览 J2EE 作为 Sun 公司所颁布的标准,已经为工业界广泛接受,J2EE 的出现标志着用 Java 开发企业级应用系统已变得非常简单。 图2-1 J2EE 体系结构 如图 2-1 所示,J2EE 是多层的分布式体系结构,使系统的操作和运行具有很好的灵活 性。先进的 Java 计算方案如面向对象、独立于平台、快速集成、代码重用等,是实现这种 结构的关键,并使系统具有良好的可移植性和可扩展性。 多层分布式应用模型意味着应用逻辑将根据功能分成几个部分,用户可以在相同或不同 的服务器上安装由不同应用组件组成的 J2EE 应用。应用组件的安装位置取决于应用组件在 多层 J2EE 环境中属于哪一层。参照上图,这些层次定义如下: 2.2.1.1 第一层:客户端层 可以是在客户端层内运行的浏览器、基于 Java 的程序或者其它 Web 类型编程环境—— 在公司防火墙内部或外部。 13 2.2.1.2 第二层:应用服务器层 一般情况下,此层包含支持客户端请求的表示逻辑和业务逻辑。表示层由显示 HTML 页面的 JSP 页面和 servlets 实现。业务逻辑通过 RMI 对象和 EJB 实现。EJB 依靠容器 (Container)实现事务处理、生命周期和状态管理、资源池、安全等问题,简而言之,容器 就是 EJB 依赖执行的运行环境。 2.2.1.3 第三层:后端层 此层是现有应用和数据仓库的组合,也称为企业信息系统(EIS)层,因为它可以包含 企业资源规划(ERP)、大型主机事务处理、数据库系统及其它遗留下来的信息系统等许多 系统。 2.3 J2EE 的优势所在 J2EE 中强调的基于服务器端应用设计、分层体系结构设计、分布式组件、统一的标准 及平台独立等等,使得 J2EE 的优点在开发企业级应用系统的时候,具有非常明显的优势: 集成了适合商务应用的 EJB 的 Java 平台,由于其简洁的结构和跨平台的特性,可以很 好地支持快速开发和即时发布 使用 Servlet,JSP 和 EJB 做为可重用构件的应用结构使得容易集成和具有最大的生产能 力。在开发、发布、管理和重用应用逻辑等方面具有很大的灵活性。 基于工业标准保证数据交换的一致性和安全的安全网络架构,可以在应用和平台上达到 高效的集成。 因此这种开放式结构特别适合于开发电子商务系统,理由如下: 分布式环境-可以保证系统的稳定性,同时拥有较高的性能。 面向对象的模块化组件设计-可以提高开发速度,降低开发成本。 基于开放的标准:Java,XML,RMI,TCP/IP,JMS 等协议、消息传递标准和中间件做 为集成的方法 三层/多层体系结构-最适合 Internet 环境,可以使系统有很强的可扩展性和可管理性。 以应用服务器为中心-低成本,安全和高性能 可扩展-允许透明地扩展以适应电子商务爆炸式的增长 最大限度地利用现有的技术投资,采用 Java 技术-完全跨平台,适应 Internet 需要,并 能得到大多数厂商支持,进而保护用户投资。 2.4 J2EE 的规范组成 下表显示的是 J2EE 1.2 版本的规范系列及其目的: J2EE 服务 目的 分布式对象/组件 14 企业级 Java 组件(EJB) 实现业务逻辑 远程方法调用(RMI) RMI 对象的分布式执行 Java 事务 API(JTA) 事务管理 Java 事务服务(JTS) 事务管理 Java 命名与目录接口(JNDI) 对象名字的中心注册 Java 消息服务(JMS) 协调分布式执行 JavaMail 访问邮件服务器 2.4.1.1 Web/HTML Servlet 显示逻辑 Java 服务器页面(JSP) 显示逻辑 数据访问 Java 数据库连接(JDBC) 访问数据存贮 作为最新的 J2EE 1.3 版本,除了对 J2EE 1.2 中的部分规范进行更新以外,还新增了以 下几个规范: Java 连接架构(JCA) 集成企业信息系统 Java 管理扩展(JMX) 基于 Web 方式管理 J2EE 应用 Java 认证及授权服务(JAAS) J2EE 应用的安全框架 2.5 显示逻辑 在 J2EE 应用中,显示逻辑用来负责将客户端应答交给某一请求的服务器端代码。例如, 您的显示逻辑简单的可以是“当请求收到时报告现在时间”一类。编码服务器端显示逻辑可 以采用 Java Servlets、JSP、JavaBean 以及标记(Tag)库。 2.5.1 Java Servlets Java Servlets 为接受来自于 Web 浏览器端的 HTTP 请求并且返回 HTTP 应答的服务器端 技术。Servlets 可以是多线程的,比起 CGI 在编码对于 Web 客户端的显示逻辑方面有着显 而易见的性能优势。因为 Servlets 是以 Java 来书写,因此可以满足平台之间无缝兼容。Servlets 是一项定义显示逻辑开发方面的企业级 Java 标准。 Servlets 从客户端接受请求,动态生成响应(可以通过查询数据库满足请求),然后将 包含 HTML 或 XML 文档的请求发送到客户端。 Servlets 类似于 CGI,但更易于编写,因为 Servlets 使用 Java 类和流。它们的执行速度 15 也更快,因为 Servlets 可编译为 Java 字节代码,在运行时,Servlet 例程驻留在内存中―― 每个客户端请求都生出一条新线程。Servlets 易于以动态形式向 HTTP 响应流产生数据。 Servlets 面临的问题是无状态协议,这就是说,每个请求都作为新连接执行,因而请求 之间无法实现自然的流控制。对话跟踪或对话管理能保持请求间特定客户端的状态。不过, 使用 HTTP 会话(Session)对象可以保持方法请求之间的状态。 大多数通常使用的 servlet 类型为 HTTP servlet,用来设计成面向 HTTP 协议(Web)的 请求。 HTTP Servlets 提供以下几个核心功能: HttpRequest 对象捕获请求的详情,请求是由 Web 页面形式的表格所提交的,其中包括数据的可用 性、协议类型、安全级别等等。 HttpSession 对象特定于每个用户,以操作服务器中的用户会话信息。Servlet 开发者在 servlet 运行 过程中可以添加和删除此用户的信息。 HttpResponse 对象捕获应答的详情。Servlet 开发者可以输出任何信息传送给发出请求的那个客户端。 Servlet 引擎处理余下的那些部分。 2.5.2 Java 服务器页面(JSP) JSP 技术给开发人员一个简单的,HTML 类似的接口来创建 servlets。JSP 可以包含 HTML 代码、Java 代码以及被称为 JavaBean 的编程模块。JSP 技术提供与 servlets 同样的功能,只 不过开发接口更容易使用。当 JSP 页面第一次被请求的时候,应用服务器将页面编译成 servlet。Servlet 然后执行来服务进一步的请求。用这种方法,servlet 引擎和 JSP 引擎被紧密 地捆绑在一起。 JSP 页面的好处首先在于它们的简便性:它们看起来很象典型的 HTML 页面。实际上, 您可以在一个标准的 Web 构建工具如 Macromedia Dreamweaver 中编辑 JSP 页面。 其次,JSP 页面提供 Servlets 的所有优点,如果与 JavaBeans 类结合在一起,可以容易 地将内容和显示逻辑分开。将内容和显示逻辑分开的优点是无需了解 Java 代码就能更新页 面的外观,更新 JavaBeans 等级的人也无需深入了解 Web 页面的设计。用户可以使用带 JavaBeans 的 JSP 页面定义 Web 模板,以便建立由外观相似的页面组成的 Web 站点。 应该说,JSP 页面和 Servlets 都比通用网关接口(CGI)应用更为广泛,因为 CGI 依赖 于平台,消耗资源更多,而且程序不能容易地访问参数数据。 16 2.5.3 JavaBeans 和标记(Tag)库 JavaBean(和 EJB 区分开)是 Java 组件(类),开发人员在 J2EE 应用中用它来封装来 自于数据库中的数据,或者进行显示或者进行操作。开发人员创建带有若干个方法的类文件, 这些方法典型地用来获得或设置某些值。JSP 页面有一些特别的标记(Tags),其中包含 JavaBeans 并且自动用值来填充这些标记。JSP 页面调用那些 JavaBeans 中的方法来帮助创建 它的 HTML 输出。 标记库提供 JSP 页面中使用的可定制 HTML 形式的标记(Tags)。标记库抽象 Java 代 码为标记,以便于由 Web 编辑和设计人员进行操纵。为了建立一个标记库,开发人员创建 类文件和一个称为标记库描述器的文件列出标记库中可用的那些标记。 JavaBeans 与标记库管理那些通过 JDBC 访问的数据源和 EJB 进行互操作的数据与 Java 代码。JavaBeans 与标记库作为一项有价值的服务,使得 Web 应用开发人员可以将 JSP 页面 和 servlets 中那些显式的 Java 代码单独拿出来。这种模块化的方式可以将某一 HTML 编辑 会话过程中对 JSP 页面偶然毁坏的机会最小化,并且可以允许显示逻辑可以独立于 JSP 页面 进行修改。 2.6 数据库和事务支持 数据库和事务支持由 JDBC 和 JTA/JTS 来“幕后”提供。对数据库使用的高级别的接口 由 EJB 来提供。 2.6.1 Java 数据库连接(JDBC) JDBC 数据库连接方面的 Java 标准。JDBC 规范由一系列标准的 Java API 的集合来提供 连接数据库所需要的所有事情。厂商提供 JDBC 驱动器,映射标准 Java API 集到底层数据 库的那些特定的接口。 从编程的角度来讲,JDBC 是连接 J2EE 应用服务器到数据库的一座桥梁。此功能对编 程人员来说是透明的:它由 EJB 来提供。开发人员除非在特别的情况下一般不直接用 JDBC 来编程。 典型的 J2EE 应用依赖于某一数据库来提供那些关键的电子商务应用功能比如事务支 持、并发的数据访问支持以及数据完整性功能。关系型数据库支持一种通用的访问语言称为 SQL。 JDBC 提供以下功能: 用来修改数据库的 API 17 此类操作包括 SQL 更新和管理命令。 通过建立 SQL 查询语句从数据库中读取数据的 API 此类查询返回 ResultSet Java 对象,返回 JDBC 数据库查询的结果。这些对象使得 J2EE 开发人员可以编程访问(通过标准 API)由某一给定的 SQL 查询返回的那些值。 支持基本的事务 JDBC 提供针对简单 SQL 语句的自动提交。因此,一个简单的单个方法调用可以直接 将一个 SQL 语句传递给数据库,并且修改自动提交到数据库中。 支持复杂的事务 JEEE 应用服务器提供一个称作 JTA 的服务,通过它来提供开始事务的能力且可以跨越 J2EE 服务和 JEEE 应用服务器之间进行传播。 JDBC 驱动程序可以由数据库厂商或应用服务器厂商进行实现。一般来讲,共有以下四 种不同类型的 JDBC 驱动器: 第一种是 JDBC-ODBC 桥,与 JDK 一起配合。它更象一种概念证明,还不能用于正式 的生产环境。借助它,可以将应用与任何 ODBC 源连接在一起。. 第二种驱动程序借助本地库与关系数据库通信,例如在 Oracle 中是 OCI 库。这意味着 必须在客户端上提供本地库。 第三种驱动程序是多层的,即驱动程序位于客户端和 RDBMS 中间。它建立与 RDBMS 的连接,是所有请求和响应的通道。客户端只需加载纯 Java 就能与第三种驱动程序通信。 第四种驱动程序与第二种驱动程序相似,但它不使用本地库,而是借助专用协议直接与 RDBMS 通信。 2.6.2 Java事务 API(JTA)/Java 事务服务(JTS) J2EE 事务处理模型可以在部署过程中定义组成一个事务处理的方法之间的关系,以便 事务处理中的所有方法可以作为一个整体存在。用户一定希望完成这一任务,因为事务处理 是一系列步骤,要么全部执行成功,要么全部回滚。 例如,EJB 中可能有一系列方法,其作用是将资金从一个帐户转移到另一个帐户,方法 是借记第一个帐户和贷记第二个帐户。用户可能希望将全部操作作为一个整体,这样,如果 借记之后、贷记之前出现故障,借记将滚回。 事务处理属性在应用组件的集成过程中上确定。它可以将各种方法组合成应用组件间的 事务处理,即用户可以在 J2EE 应用中容易地重新分配应用组件的事务处理属性,无需修改 代码和重新编译。 Java 事务处理 API (JTA) 和 Java 事务处理服务(JTS)形成 J2EE 中事务处理支持的基 18 础,而且更适合 EJB 和 JDBC 2.0。 JTS 是低级事务处理管理 API,主要作用是将 Java 映射到对象管理组(OMG)的对象 事务处理服务。 JTA 给于 Web 应用开发人员访问数据库系统或任何遗留数据存贮中的事务功能。事务 协调单个数据库和多数据库操作来确保所有的数据资源保持精确型和一致性,并且那些对数 据库的操作是可以重复和持久的。事务管理对于那些面向 Web 和容错性的企业级电子商务 应用来说是最基本的。JTA 定义了一个对于分布式应用的资源管理器的高级别事务管理规 范,包括两个部分: 事务处理接口 允许事务处理定界。完成工作的方式是分布式组件由全局事务处理登 记。这种方法可以使多组操作组成一个事务处理。 XA 资源接口 基于能处理分布式事务处理的 X/Open/XA 接口,有时也称为两阶段提交事务处理,需 要多种资源之间的协调,如数据库或序列。应用服务器应能支持多种事务处理,包括 EJB、 JMS 和 JDBC 操作。分布式事务处理由两阶段提交协议协调,可跨越用 XA 兼容的 JDBC 驱 动程序访问的多个数据库。 EJB 规范定义了 Bean 管理的事务处理和容器(Container)管理的事务处理两种事务处 理方式。当 EJB 用容器(Container)管理的事务处理部署时,J2EE 应用服务器将自动协调 事务处理。如果 EJB 由 Bean 管理的事务处理部署,EJB 参数必须提供事务处理代码。 基于 JMS 或 JDBC API 的应用代码可以启动事务处理,或参与先前启动的事务处理。 一个事务处理联系与执行应用的 J2EE 应用服务器的线程相关,所有事务处理操作都在参与 当前事务处理的线程上执行。 多数情况下,用户无需担心用 JTA 编写明确事务处理的问题,因为此项工作由 JDBC 完成,EJB API 由容器(Container)处理,并由应用部署说明符来配置。这样,用户就可以 将精力集中在事务处理设计而非实施上面。 2.6.3 对象注册和远程方法调用(RMI) JNDI 和 RMI 支持命名服务与远程方法执行。 19 2.6.4 Java命名和目录接口(JNDI) 由于 J2EE 应用的组件可以独立运行,而且通常是在不同设备上运行,因此客户端和应 用服务器层代码必须以某种方式查找和参考其它代码和资源。JNDI 就是一项用来中心注册 命名和目录服务的 Java 标准。 JNDI 管理创建分布式应用中所需要的那些核心组件的引用,当一个开发人员创建一个 访问远程对象的应用时,JNDI 提供给应用一种途径来定位对象。JNDI 技术是命名和目录服 务的接口,用来对那些命名的应用与数据对象进行中心注册。JNDI 服务帮助确保应用组件 名字的唯一性,并且帮助预防、诊断和处理可能引起的命名冲突。 JNDI 的使用模板相对简单。应用开发人员在应用服务器(如 WebLogic)部署环境中通 过初始化的 lookup 来查找到所需要的对象。应用服务器中的 JNDI 服务将返回应用所需要的 访问该对象的所有内容。 2.6.5 远程方法调用(RMI) RMI 是 Java 应用用来调用远程对象的方法一项 Java 标准。RMI 使得远程对象虚拟成就 好象它们对应用来说在本地一样。RMI 为您的分布式应用提供与远程客户端通过远程方法 和服务进行操作的框架。允许 RMI 调用的远程主机公布远程对象的那些方法。对象可以定 位在跨越网络或可能跨越您的 J2EE 应用服务器(如 WebLogic)群集中的另一应用服务器 的实现之上。 2.7 企业级 Java 组件(EJB) EJB 是以 Java 来创建服务器端业务逻辑的企业级 Java 标准。与显示逻辑自动处理将要 显示给客户端的类型和格式信息相对应,业务逻辑用来操作诸如基金转帐、产品定单等等。 开发人员可以充分利用 J2EE 应用服务器作为 EJB 容器所提供的服务来创建 EJB。 EJB 组件用于封装业务逻辑,使得开发人员无需再担心数据访问、事务处理支持、安全 性、高速缓存和并发等琐碎任务的编程。在 EJB 规范中,它们由 EJB 容器(Container)来 负责。EJB 容器提供给开发人员创建如基金转帐、雇员记录管理或其它功能等的业务逻辑所 需要的任何事情。 EJB 包含接口和类。客户端通过 EJB 的本地接口和远程接口访问 EJB 方法。本地接口 提供的方法可用于生成、删除和查找 EJB,远程接口则提供业务方法。部署时,容器 (Container)从这些接口生成类,这些类使客户端可以访问、生成、删除、查找 EJB 和调 用 EJB 上业务方法。EJB 类为业务方法、生成方法和查找方法提供实施,如果 Bean 管理自 己的存储,还得提供生命周期方法的实施。 20 有以下四种基本类型的 EJB: 实体 消息驱动 有状态会话 无状态会话 2.7.1 实体 EJB (Entity EJB) 实体 EJB(entity beans)为代表数据的企业级 Java 标准。它们是驻留在 EJB 容器中的 标准 Java 语言对象。 大多数情况下,实体 beans 代表从数据库中来的数据,尽管它们也可以代表存贮在其它 位置的数据。在 J2EE 应用服务器部署环境中,beans 代表存贮在某一关系型数据库中的数 据,比如 Oracle、IBM 的 DB2、Informix 等等。 象实体 beans 之类的对象需要映射到某一关系型数据库管理系统(DBMS)的关系结构。 在针对员工信息表的关系数据库中,表中的每一行就是一个 Bean 的实例。实体 EJB 是 事务处理型和持久的。只要数据存在于数据库中,实体 EJB 就存在。这种模式可容易地用 于关系数据库,而且不限于对象数据库。 用容器(Container)管理的持久性访问关系数据库的 EJB 不需要为数据库访问使用任 何 JDBC 2.0 API,因为容器(Container)可以负责完成这项任务。但是,如果使用 Bean 管 理的持久性或想访问关系数据库以外的企业信息系统,就需要提供相应的代码才能完成。 如果 EJB 使用由 Bean 管理的持久性访问数据库,用户必须借助 JDBC 2.0 API 实施 Bean 生命周期方法,这样才能加载和保存数据,并保持运行和持久数据库存储之间的一致性。 Web 层使用 HTTP 或 HTTPS 在各层之间传输数据,EJB 层则使用 RMI-IIOP。RMI-IIOP 是一种完全可扩展的分布式计算协议,使访问 EJB 的任何客户端或 Web 层程序能直接访问 EJB 层中的服务。这些服务包括用于查阅和参考 EJB 的 JNDI、用于发送和接收异步消息的 Java 消息服务(JMS),以及用于关系数据库访问的 JDBC。 EJB 规范定义了针对开发人员创建、部署和管理跨平台、基于组件的企业级应用的一个 API。EJB 组件模型支持以下三种类型的组件: 会话 beans,用来捕获会话持续过程中的业务规则和方法; 实体 beans,封装来自于某一数据库的特定数据项; 消息驱动 beans,集成 EJB 和 Java 消息服务(JMS) J2EE 应用服务器自动地处理某些活动诸如管理事务、并发问题、安全及其它功能,因 21 为 EJB 容器提供了这些服务。在进行 EJB 编程的时候,开发人员无需担心这些低级别的问 题:容器来负责这些事情。 2.7.2 会话 EJB(Session EJB) 会话 beans 代表与客户端的短暂对话,可以执行数据库读写。会话 beans 可以请求 JDBC 调用本身,也可以使用实体 beans 执行调用,这时会话 beans 是实体 beans 的客户端。会话 beans 的字段包含对话的状态,是短暂的。如果服务器或客户端出现故障,会话 beans 将消 失。这种模式一般用于 PL/SQL 等数据库编程语言。 企业级 Java 标准定义了两种类型的会话 beans:有状态和无状态。 无状态 beans 接受由 RMI 方式送过来的请求但是内部并不保存它所服务客户端相关的 任何数据。它们一般提供不保留任何状态的服务器方行为。无状态会话 beans 需要的系统资 源较少。提供通用服务或表示共享数据视图的业务对象适合作为无状态会话 beans。 有状态 beans,另一方面,保存它所服务的特定于客户端的数据。对话状态是无状态 beans 实例的字段值加上可以从无状态 beans 字段阅读的所有对象。有状态的无状态 beans 不表示 持久数据库中的数据,但能够以客户端的名义访问和更新数据。 从开发人员的角度来看,这两种类型的会话 beans 在创建时相类似。不过,EJB 容器对 待它们的处理方式却是截然不同的。 会话 beans 处理由 RMI 方式递送来的请求。典型地,它们为其它的 Java 对象提供服务。 这一点与 servlets 和 JSP 相对应,因为它们主要聚焦在应答那些由如 Web 浏览器等 Web 客 户端发出的请求(这些请求是以 HTTP 方式到达的)。 发出请求到会话 beans 的对象可以是任一对象,只要它能够访问合适的 RMI 客户端的 类。在 J2EE 应用服务器部署的环境中,这些 Java 对象典型地是那些应用客户端。然而,servlets 与 JSP 也有可能成为会话 beans 的 RMI 客户端。使用会话 beans 为您的应用客户端、servlets 或 JSP 来实现服务器端的业务逻辑 2.7.3 消息驱动 Bean(Message Driven Bean) 通过版本 2.0 的 EJB 规范,在企业级 Java 应用中增加了一个完全新的类型的 EJB 及使 用一种完全新的执行机制的选择。在实体 beans 和会话之间,使用一种异步的编程模型。客 户建立到 EJB 的请求然后从它的需要出发等待工作的完成。使用消息驱动 beans(MDB), EJB 并不附着到某一客户端,而是附着到 JMS 中定义的某个消息队列(message queue)或 话题(topic)。当某个消息到达时,EJB 的某个方法即被执行。 22 MDB 对于企业级 Java 应用引入了一种异步处理机制。任务可以进行排队然后在资源可 用时进行处理。 当您的应用需要对任务的异步处理如发送 email 应答或列表当月彩票的赢家时,使用消 息驱动 beans 就是当然的选择。 2.8 Java 消息服务(JMS) JMS 规范为开发人员针对企业级 Java 消息服务如可靠队列、发布和订阅通讯及各种目 的的推/拉(push/pull)技术等提供一系列的标准 Java API。JMS 是针对消息方面企业级 Java 标准。它使得 Java 类应用和组件发送和接收消息。 换言之,JMS 是支持 Java 程序间消息交换的 J2EE 机制。这也是 Java 支持异步通信的 方法――发送者和接收者无需相互了解,因而可以独立操作。 JMS 中的消息有几种机制,其中包括: 队列模型 队列模型使得 JMS 客户端可以将消息放到 JMS 队列中。客户端然后取出这些消息。 具体的过程是:消息产生者将消息发送到队列中。消息消费者可以将自身与队列连接, 以倾听消息。当消息到达队列时,客户可以从队列中取走,并给出响应。消息只能发送到一 个队列,只能由一位消费者使用。消费者可以过滤消息,以便获得希望获得的消息。 基于话题(topic)的,发布-订阅系统 基于话题的模型使得发布者发送消息给某一 JMS 话题(topic)的注册过的那些订阅者。 这种情况下,许多消费者都能接收到同样的消息。 2.9 Java 接口定义语言(IDL) CORBA 对象使用 IDL 确定接口(怎样与其它对象交互)。借助 Java IDL,可以定义 Java 应用和 CORBA 应用之间的合同。 为使用 Java IDL,应使用可以产生便携客户端存根(Stub)和服务器骨架(Skeleton)的 idltojava 编译器,此编译器可以与任何 CORBA 兼容型对象请求代理(ORB)一起使用。从 Sun 的 JDK 1.2 开始包含 ORB,使 Java 应用能通过 IIOP 协议请求远程 CORBA 对象。 2.10 JavaMail JavaMail API 提供支持简单 email 和消息服务以及连接到任何标准 email 系统的那些类。 JavaMail 接口提供了一个标准的、面向对象的协议来连接到众多不同类型的 email 系统中。 23 2.11 安全 J2EE 安全模型可用于配置 Web 或 EJB 组件,目的是只允许授权用户访问系统资源。例 如,Web 组件可配置为提示输入用户姓名和口令。EJB 组件可配置为只允许某些组内的人请 求某些方法。 同样,servlet 组件也可以配置为允许所有人访问其方法,或根据 HTTP 请求方式来进行 安全认证。servlet 组件还可以为另一环境配置,允许所有人访问所有方法,或者只允许一些 人访问所有方法。 实现 J2EE 的应用服务器(如 WebLogic)通常拥有非常强大的访问控制列表(ACL) 机制,可以精确控制服务器上运行的组件的使用权限。它允许在 Java 方法等级确定哪个或 哪组用户可以或不可以执行哪些操作。这种 ACL 机制包含 J2EE 应用服务器上运行的一切, 但 EJB 除外。EJB 有自己的访问控制机制,定义在 EJB 规范中。 安全领域使管理员能将信息从现有授权或认证系统输入到 ACL 中。 因此,用户可以从 NT 安全系统、LDAP 系统、Unix 口令文件或数据库中导入信息,以这些安全领域用户的身 份来进行访问。 不过,J2EE 安全模型仍然在发展过程中。其中的一项规范 — Java 验证和授权服务 (JAAS)提供一个框架来验证客户端并且授权对应用资源的不同访问。 2.12 J2EE 客户端 J2EE 客户端可以基于 Web,也可以基于 Java。基于 Java 的客户端使用 Java RMI 访问 服务。这种情况下,Java 客户端应该是 Servlet 或 EJB。总之,分布式企业应用可能同时包 含两种客户端。 在 JavaScript 等技术的帮助下,Web 浏览器可以支持强大、快速的用户界面。其它功能 可以由小应用程序(Applet)提供。借助 HTTP 上的 HTML 或 XML,Java 小应用程序可以 与浏览器一起使用,以便获得进一步增强。Java 小应用程序还可以与中层通信,以便进一步 加强控制和提高灵活性。Web 浏览器是真正的通用 Web 客户端,对简单用户界面和 Internet 应用来讲,它是理想的客户端。 最重要的规律是,如果 HTML 足以捕获和显示应用所需的信息,则 HTML 为首选。使 用 HTML 的实际原因是,用户对客户端方没有控制力。 如果 HTML 不足以捕获和显示应用所需的信息,则应该由客户端执行必要的捕获和显 24 示操作。无论是小应用程序还是独立 Java 程序,都应该使用 Java 客户端,因为它们可以提 供更丰富的图形用户界面。 在 Internet 中,小应用程序代表一系列逻辑问题,可能会降低用户对计算机的满意度。 因此,我们建议只限在网络带宽较高而且浏览器类型可以控制的公司内部网中使用小应用程 序。 某些情况下,HTML 和 Java 都不适合生成 GUI。由于 Microsoft 拥有台式机,因此实际 方法可以允许与 COM 进行某种连接。如 WebLogic jCOM 技术,就可以在 Visual Basic 中编 写 ActiveX 组件,与 Excel 电子数据表一起与基于 J2EE 的应用交互。 关于 JavaScript、DHTML 和样式 HTML 内容已得到浏览器和操作系统的广泛支持。与 HTML 一起,服务器还可以提供 JavaScript 代码,以便根据要求丰富用户界面。这种内容最适合响应展示产生在服务器方但 需传送到浏览器显示的情况。它应该作为标记语言,指导浏览器怎样展示结果。HTML 是 对静态文档进行编码的好方法。但是,借助 HTML 很难展示复杂文档。样式页和动态 HTML (DHTML)可以显示更复杂的文档。但是,各种常用的浏览器不能处理样式页和 DHTML 一致性,因此需要设计各种形式的页面或在页面中包含浏览器专用标记。 HTML 的优势是已经得到了许多平台上多种应用的广泛支持。在最常用的浏览器上, 不依赖浏览器专用标记的 HTML 文档应该外观相似。HTTP 与 HTML 的结合可以保证能够 在许多平台上查看文档。 第3章 表示层应用构建 对于一个采用 J2EE 的应用系统,其表示层不能狭义理解为用户界面,实际上,按 照多层体系结构的划分来说,表示层涵盖了所有用户接口,所连接的客户端可以是浏览器、 Java client 端、WAP 手机,甚至是 VB 或者 PB 编写的客户端,所有这些客户端通过应用服 务器的表示层的应用和系统后端的商业逻辑层以及数据存取层进行相应操作。系统的框架如 图 3-1 所示。 25 InternetInternet VBVB PowerBuilderPowerBuilder JavaJava Presentation & Business logic WebLogic Server (Cluster) JDBC Web Server 图 3-1 WebLogic 多层应用体系结构 一个基于 J2EE 多层架构开发的系统,表示层除了通过 JSP、Servlet 和 HTML 的展 现以外,还可以包括如 e-mail 等接口。为了与企业中现有的其他应用结合,基于 J2EE 平台 构建的应用,还应该为传统的 Client/Server 体系结构下的客户端提供访问接口。随着 Web 技术的普及,Web Service 作为一种基于 HTTP 的服务,为这些用户提供了可以访问 J2EE 平 台上应用的接口。 本章首先介绍基于 J2EE 规范的表示层应用的技术实现,包括 JSP 技术、Servlet 以及 XML 和 Taglib,然后介绍 Web Service 技术,利用它向各种类型的客户端提供服务访问接口, 最后介绍几种常用的表示层开发设计模式。 3.1 表示层技术实现 对于 J2EE 应用的而言,表示层的客户端同样是一个 Java 的应用程序,但与独立的 java 应用程序的客户端不同,J2EE 的客户端是 J2EE 的组件。与其他 J2EE 组件类似,可以与 J2EE 其他组件一起开发、部署和使用。最常用的客户端组件包括 Servlet 和 JSP,在本节中,我 们将对这两种技术加以介绍。JSP 和 Servlet 的主要目的是为 WEB 应用提供动态访问的内容 信息,这些信息与静态的 HTML 信息一起形成反馈信息,展现给最终用户。图 3-2 显示了 JSP 和 Servlet 的主要功能。 26 静态内容 HTML 动态内容 JSP 页面 和 Servlet 数据库 JDBC 图 3-2 JSP 和 Servlet 的主要功能 而随着越来越多的应用采用 J2EE 架构来实现,系统逐渐变得庞大和复杂,这时简 单的采用 Servlet 和 JSP 技术来构建表示层应用,就显现出其局限性,包括在构建内容方面、 访问系统逻辑信息、请求综合处理等方面。因此页面构建不再仅仅是简单的 Servlet 和 JSP 集成,而是逐渐增加了对 JavaBean 或者 EJB 的访问,利用自行定制的 JSP 标记以实现某些 特殊功能,以及利用一些设计方式来实现业务功能。由于 JSP 和 Servlet 均是 J2EE 的组件, 它们可以直接使用其他的 J2EE 组件所提供的服务;而页面设计变得复杂之后,我们有必要 通过模块化设计,模板式开发来简化复杂系统的设计和实现,并结合其他服务以改善表示层 的设计,可以使复杂的系统依旧可以具有良好的可维护性、健壮性等特点,图 3-3 显示了随 着页面技术组件化和系统健壮性之间的关系。 27 HTML 页面 基础的JSP 和Servlet JSP页面 和模块组件 JSP页面 和模块组件 以及EJB 复杂度 健 壮 性 HTML 页面 HTML 页面 HTML 页面 HTML 页面 JSP 页面 和 Servlet JSP 页面 和 Servlet JSP 页面 和 Servlet Java Bean 组件 Java Bean 组件 自定义 的标签 自定义 的标签 模板 EJB 图 3-3 页面复杂度和健壮性间的关系 3.2 Servlet 3.2.1 Servlet 概念 Java Servlet 技术为 Web 服务器提供了强大的扩展功能。它实际上是一个运行于服务器 端的 Java 应用程序,可以生成与 Web 服务器无关的动态内容。一个基于 Web 的应用,其 客户端是浏览器,它会通过 HTML FORM 的提交方式来调用 Servlet, 当 Servlet 执行后会 产生相应的 HTML 或者 XML 输出到用户端的浏览器上。 由于 Servlet 利用 Java 语言编写,与其他 Java 应用程序一样,它同样具有 Java 语 言的跨平台性,便于移植,并且可以使用任何服务器端所提供的资源,包括通过 JDBC 访问 数据库、RMI 远程方法调用、访问 EJB 和 JMS 服务等等。Servlet 利用 Java 语言扩展了 Web 服务器的功能,它的执行效率远远高于 CGI 脚本。一个 Servlet 只需要一次加载到内存,而 后无论多少次的调用均是在内存中执行,无需再要求其他的硬件资源。当 Servlet 加载到内 存中时,它以一个轻量级的线程来运行,而不象 CGI 那样每个请求由不同的进程来执行。 同时 Servlet 也可以利用缓存技术(如使用 ServletContext 或者 Session 对象)来保持用户连 接信息以及其他的 Java 对象。 28 HTTP Servlet 降低了从 HTTP 请求获取信息的复杂程度,由于请求信息中的参数以 HTTPRequest 对象的形式存在,所以 Servlet 中的组件可以直接访问这些资源。另外 Servlet 还提供了统一的 API 来管理整个应用过程中会话信息变量(Session),因而可以有效的克 服的 HTTP 协议无状态的限制。 Servlet 提供了一系列的服务来满足 WEB 应用的客户端访问,这些功能包括: 会话信息跟踪 – 允许 WEB 应用跟踪一个用户访问多个 WEB 页面的过程。这种功能对 一个网上购物流程的开发带来便捷,同时通过服务器端的会话信息保存和信息复制的容错处 理可以有效地提高系统容错处理能力。 数据库访问 – Servlet 可以利用 JDBC 驱动程序直接访问数据库,获取动态信息。而利 用 WebLogic 提供的多层 JDBC 数据库驱动程序,还可以使用连接缓冲池、数据缓存等更为 丰富的功能 安全管理 – Servlet 可以结合 SSL(Secure Socket Layer,安全套接口)进行用户验证, 同时利用 ACL(访问控制表)可以有效地配置服务器端访问各种资源的用户权限限制。 EJB 和 JMS 的访问 – Servlet 可以直接作为 EJB 或者 JMS 的客户端,来调用 EJB 的服 务,或者通过 JMS 进行消息的发送和接收。 Servlet 的访问模型和生命周期 Servlet 的访问模型 图 3-4 显示了 Servlet 基本的访问模型。客户端通过发送一个请求到 WEB 服务器 端来初始化一个文本请求。如果这个请求与注册在 WEB 服务器上的一个 Servlet 匹配,则 WEB 服务器就会执行相应的 Servlet,这 个 Servlet 负责生成响应发送回客户端,响应的格式 与客户端发送来的请求需要一致。由于 Servlet 是运行于服务器端,它能够访问到很多服务 器端的资源,如前面介绍过的 DB、EJB 和 JMS,还包括诸如文件系统、JNDI 服务以及目录 服务等。 29 图 3-4 Servlet 访问模型 Servlet 的生命周期 Servlet 的生命周期定义了一个 Servlet 何时被加载进来,如何接收和处理请求并生成相 应的响应以及如何卸载服务。反映在代码中,其实际的生命周期都在 javax.servlet.Servlet 接 口中进行了定义。 实际上,Servlet 是运行在服务器的 Servlet 容器中,这个容器是服务器环境的一个组成 部分,Servlet 的生命周期、安全管理和执行环境等都由这个容器决定,换句话说,Servlet 容器负责生成、调用和卸载 Servlet。同时该容器也提供了一个在客户端和 Servlet 之间传递 信息的机制,因此也可以认为服务器是请求和应答之间的中介。 图3-5 演示了Servlet 的生命周期。Servlet 引擎(WEB服务器的一部分)负责实例化Servlet 并将其加载到 Servlet 容器中,实例化和加载的过程可以发生在服务器启动的时候,也可以 在客户第一次请求该 Servlet 服务的时候进行。WEB 服务器负责将 Servlet 实例化,在 WEB 服务器实例化好 Servlet 之后,WEB 服务器通过 Servlet 的 init()方法对该 Servlet 进行初试化, 这个处理可以包括:从数据库读取信息、建立同其他资源之间的关系或者执行其他费时的操 作。当一个请求从浏览器发送到 WEB 服务器时,WEB 服务器将用户请求转化为 ServletRequest 对象,然后 WEB 服务器会调用 Servlet 的服务方法来处理这个请求(包 括:service(),doGet()和 doPost()方法)。在某一时刻,可能是设置的超时时间到了,或者是服 务器关闭的时候,Servlet 进入到卸载阶段,它的 destroy()方法会被调用,WEB 服务器调 用该方法一次性进行关闭的操作,而当 Servlet 被 WEB 服务器卸载后,那么 JVM 就可以对 其进行垃圾回收了。 图 3-5 Servlet 的生命周期 30 3.2.2 JSP 技术 3.2.2.1 JSP 简介 JSP(Java Server Pages TM)技术为创建显示动态生成内容的 Web 页面提供了一个简捷 而快速的方法。JSP 技术的设计目的是使构造基于 Web 的应用程序更加容易和快捷,而这 些应用程序能够与各种 Web 服务器、应用服务器、浏览器和开发工具协同工作。它继承了 Servlet 的优点,同时它还提供了快速的开发模式,并将内容和显示的逻辑相分离,可以在 基于组件的架构体系下重用代码。而在实际运行时,JSP 首先是被 JSP 引擎翻译为 Servlet, 然后再如同 Servlet 一样编译和调用执行,因此 JSP 也有着和 Servlet 一样的生命周期和访问 模式。 事实上,Servlet 和 JSP 都讲述了如何处理一个 HTTP 请求,产生相应的响应。而 Servlet 主要是利用 Java 语言来实现,而 JSP 页面则是一个纯文本的文档结构,它结合了 HTML 和 JSP 标记,Java 代码以及其他信息。尽管两者都用来解决类似的问题,但各自有所侧重。Servlet 技术提供了一个接收用户从浏览器发送来的请求,从应用逻辑层和数据库获取相应的信息, 根据请求的数据信息执行应用逻辑,然后将执行结果输出到浏览器。Servlet 利用 print 方式 将结果形成 HTML 输出到用户端的浏览器上。通过 print 方法将生成 HTML 页面会造成两个 问题,一,由于 HTML 页面的信息是通过 print 方法形成的,Web 页面的设计人员无法设计 和任意修改页面;二,当数据的显示格式发生变化,你在 Servlet 中需要寻找有关的代码, 而且修改代码后还需要重新编译代码和重新部署到服务器中。 而 JSP 则提供了一种从 JavaBeans 到 HTML(XML)等表示元素之间的映射机制,由于 JSP 是基于纯文本方式开发,Web 页面的设计人员可以使用任意的图形化开发工具来进行页 面的设计和修改,并实时查看页面效果。同时应用开发人员还可以利用同样的开发工具进行 JSP 脚本的编写,例如:从 JavaBeans 或者 EJB 获取数据,从数据库获取信息等等。利用 JavaBeans,开发人员可以将信息封装成组件或者构建自定义的标记库,对于页面的设计人 员而言,他无需了解 java 代码,就可以根据开发人员提供的信息进行页面的设计工作。当 页面的设计人员修改的 JSP 页面时,该页面会自动重新编译和部署到应用服务器中,另外在 WEB 应用中的 JSP 页面还可以在部署应用之间就预先编译完成,这样的就可以极大的提高 了系统的效率。JSP 允许内容的开发人员和 WEB 应用的设计人员明确定义应用的逻辑和内 容显示,同时无需了解 JAVA 代码。而实际的逻辑程序开发人员可以更加专著于业务逻辑的 开发,通过封装 JavaBeans 和自定义标记库,而无需关心用户界面的设计细节,这样对于一 个大的系统的开发,可以有效的划分人员的工作职责和范围。 与 Servlet 相似,JSP 也为提供动态信息创造了一种有效的途径,同时具有易于在平台 间移植与应用相独立的特点。JSP 还可以使用很多可重用的组件,包括 JavaBeans 和自定义 的标记库等。在 JSP 中所使用的 JavaBeans 与用于封装 AWT 或者 JFC 的 JavaBeans 不同, JSPJavaBeans 组件只是简单的将 get 和 set 方法显现在外部,而自定义的标记则可以认为是 一种比较智能的 JavaBeans 组件,但其动作可以更好的和 JSP 页面交互。 总之,JSP 提供了一种简单的方式来开发基于 Servlet 的动态内容,但其自身还具有将 内容和显示逻辑相分割的特点。一个好的设计 JSP 页面中,内容和应用逻辑可以是相互独立 的,并且相应的内容可以是被专著于不同应用的开发人员来修改。 JSP 应用开发模式 31 JSP 规范规定了 4 种应用程序模式,应用程序模式是一个应用的架构或者模式,它用于 定义 JSP 如何与 Servlet、HTML、HTTP、XML、Applets、JavBeans、EnterpriseJavaBeans 以及服务器端的其他组件相互协作。 通常情况下,界面的美工人员和开发人员会一起合作来决定哪种开发模式更合适,他们 需要将 web site 进行映射,决定提供什么样的服务给用户。针对 web 页面的布局来决定应用 模式。 简单模式(Simple Model) 图 3-6 简单模式 在简单模式中资源是直接访问的,该种模式取代了传统的 CGI 结构,它允许 JSP(Servlet)来访问外部资源,如 DB 或着现有遗留系统。采用此种方式的优势在于,它 易于编程,对动态的内容进行编程可以根据请求的不同和使用资源状态册不同而加以控制。 其劣势在于,由于共享和建立对资源的连接,而使得其可扩展性不强。 简单模式的优势在于简单,请求被 JSP 所处理,同时 JSP 也处理所有的商业逻辑, 可能会用到 DB 和 EJB,然后产生响应。由于所有的事情都是 JSP 处理,这就能够十分容易 地处理请求和产生响应。 转发委托模式(Forward Delegation Model) 32 图 3-7 转发模式 转发委托模式能够将一个请求从一个 JSP 链接(chaining)或转发(forwarding) 到另一个 JSP。在此种模式中,初始的 JSP 接收请求,同时可能建立或更新服务器端的对象, 然后将请求转发给另一个 JSP。如果数据已经发送回客户端时,转发的动作就不能继续。为 了避免此种情况的发生,利用缓冲区将信息保存,在最后一个处理的 JSP 页面中,将缓冲区 内容取出,并生成响应发送给客户端。 转发模式可以将接收请求的 JSP 与生成显示信息的 JSP 相分离,初始的 JSP 根据请 求信息的细节,建立或者更新服务器端的对象,将请求转发给相应的 JSP,它本身并不包含 任何界面显示的信息。由于这个 JSP 不包含显示的信息,它可以也可以通过 servlet 来实现。 但采用 JSP 可以很方便的使用标记来更新服务器端的对象。而最后一个处理的 JSP 负责将界 面的显示信息发送回客户端。 该模式的一个问题是 JSP 间的工作流可能会很复杂,其优势在于每个 JSP 负责独立 的任务,JSP 则显得更简洁和易于编写。例如一个 JSP 接收请求,并将信息保存到 java beans 中,另一个 JSP 从 DB 读取信息,第三个 JSP 生成显示给用户的信息。 包含委托模式(Include Delegation Model) 33 图 3-8 包含模式 包含模式是另外一种将任务在不同 JSP 间加以分割的方式。它与转发模式的主 要区别就是,包含模式中,一个 JSP 负责接收请求和生成响应,而转发模式中一个 JSP 接收 请求,另外一个 JSP 产生响应。与转发模式相比,包含模式简化的工作流的处理,初始的 JSP 可以调用其他的 JSP 或者 servlet 来处理,当它们结束处理的时候,将结果反馈回这个初 始的 JSP。 解偶模式(Decouple Model) 图 3-9 解偶模式 34 解偶模式是由两个松偶合的应用组成,这些应用可以在 Intranet 上,也可以是在 Extranet 或者是 Internet 上。这些应用可以是点对点的关系或者是 client/server 结构的关系。 重要的是每个应用与其他应用相隔离。为了实现松解偶方式,JSP 间的通讯采用的是 HTTP 而非 RMI/IIOP。在解偶模式下,不同 app 服务器上的 JSP 可以通过 HTTP 来相互通讯。 3.2.3 使用 Taglib 和自定制的标记 采用自定制的标记库,可以扩展 JSP 所提供的功能。BEA WebLogic 应用服务器也提供 了一些针对界面设计使用的专用标记,开发人员可以在 JSP 页面的开发过程中使用。同样开 发人员可以根据实际业务需要,自行开发和设计在应用中使用的标记库。为了在 WebLogic 中使用这些标记库来开发应用,开发人员应将定制的标记库部署到应用服务器的相应目录 中,同时配置部署文件,以便 Web 应用中的 JSP 可以正确使用这些标记。 我们以 WebLogic 所提供的自定制的标记库 weblogic-tags.jar 为例,介绍一下如何在 WebLogic 中部署自定制的标记库: 从 WebLogic 服务器安装路径中的 ext 目录中将 weblogic-tags.jar 复制到包含 JSP 的 Web 应用中的 WEB-INF/lib 目录中(如果是自行开发的标记库,同样复制到该目录之中)。 在 Web 应用的部署描述文件 web.xml 中配置应用部署描述符。例如: weblogic-tags.tld /WEB-INF/lib/weblogic-tags.jar 在 JSP 中通过 directive 指令引用配置好的标记库: <%@ taglib uri="weblogic-tags.tld" prefix="wl" %> 这其中有两个参数,一个是 uri,通过该属性,JSP 的引擎会搜索相应的自定制的标记 库文件,并加载进来;另一个参数是 prefix,通过设置该属性,开发人员在 JSP 页面的设计 中,就可以使用通过该标识引用该标记库中自定制标记 自定制标记的开发和使用 在 JSP 文件中,我们可以使用自定制的标记来开发 JSP 页面,这些自定制的标记可以执 行以下的任务: 1. 产生输出,输出的标记 如果标记直接在 JSP 页面中引用,则其范围内的内容将被 JSP 形成输出 如果标记是嵌套在另一个父标记中,则输出内容则是其父标记内的评估内容。 2. 定义新的对象,在 JSP 页面中可以引用或者象一个脚本变量一样使用,一个标记引 入一个固定名称的脚本变量,或者通过 ID 属性,动态命名一个脚本变量。 自定制的标记格式可以是空白的,称为空标记(empty tag),或者包含内容体,称为内 容体标记(body tag)。这两种标记可以包含一系列属性,它们会被传递给解析该标记的 Java 类。一个空标记包含下述的格式: 35 而一个内容体标记可能是如下的形式: 所包含内容 一个标签所含的内容可以包括很多 JSP 的语法格式,甚至于其他的 JSP 标记,这被称为 内容嵌套标记,嵌套的内容标记可以多层嵌套。例如:

tagA 的内容体

你可以看到次该段文字。

Hello World! 自定制标记通常是存储于标记库,在标记库中可以包含一个或者多个的 JSP 标记,每个 标记库都是由标记库描述符文件(TLD -- Tag Library Descriptor)来定义。TLD 文件对每一 个标记的语法以及执行该标记的相应的 Java 类都作了描述。下面我们就对如何编写 TLD 以 及其执行的 java 类加以介绍。 标记库描述符的开发 标记库描述符中元素的编写是有一定顺序的,这个顺序是在 DTD 中的元素定义的顺序, 如果没有按照这个顺序来排列标记库描述符中的有关元素,JSP 引擎中的 XML 解析器就会 抛出异常信息。 下面是一个标记库描述符的例子,有关元素的语法格式和使用方式,请参考 http://e-docs.bea.com/wls/WebLogic6.1/taglib/tld.html#359051 上的有关说 明。 列表 3-8 Tag Library Descriptor (tld) 的举例 1.0 1.1 quote This tag library contains several tag extensions useful for formatting content for HTML. code weblogic.taglib.quote.CodeTag tagdependent fontAttributes 36 commentColor quoteColor 标记句柄类的开发 标记句柄类 自行定制的 JSP 标记是通过一个名为标记句柄的 Java 类来解析的,开发设计人员可以 根据实际的需要编写该句柄类。这些类接口封装在 javax.servlet,jsp.tagext 中,而详细的有关 文档可以参考:http://java.sun.com/j2ee/j2sdkee/techdocs/api/index.html 上关于句柄类的介绍。 1. 该标记句柄类实现分别两个接口:Tag 和 BodyTag。这两个接口定义了标记的生命周 期。在编写标记的处理类时,你需要实现两个接口: ①. Tag 如果自定制的标记是空标记,需要实现 javax.servlet.jsp.tagext.Tag 接口。在 API 定义中 同时还提供了一个名为 TagSupport 的类,它实现了 Tag 接口,并提供了所有缺省的空的方 法实现。 Tag 的接口定义如下: publice interface Tag { public final static int SKIP_BODY = 0; public final static int EVAL_BODY_INCLUDE = 1; public final static int SKIP_PAGE = 5; public final static int EVAL_PAGE = 6; void setPageContext (PageContext pageContext); void setParent (Tag parent); Tag getParent (); int doStartTag () throws JspException; int doEndTag () throws JspException; void release (); } ②. BodyTag 如果自定制的标记是内容体标记,需要实现 javax.servlet.jsp.tagext.BodyTag 接口。在 API 定义中提供了一个名为 BodyTagSupport,它实现了 BodyTag 接口,并提供了所有缺省 的空的方法实现。 2. 编写一个实现 Tag 和 BodyTag 接口的抽象类, 3. 继承该基类,并实现接口中定义的所有方法,同时还可以编写其他所需的方法。编 37 写方法可以参考包中的 TagSupport 和 BodyTagSupport 类,它们分别实现了 Tag 和 BodyTag 接口,并提供了缺省的方法实现。当然也可以直接编写一个类来实现上述的接口,但代码的 可维护性就相对减弱。例如下例是一个自定制的标记句柄类 HelloTag.java,我们采用直接实 现 Tag 接口的方式,其结构如下: package myTag; import java.io.*; import javax.servlet.jsp; import javax.servlet.jsp.tagext.*; public class HelloTag implements Tag { private PageContext pageContext; private Tag parent; public HelloTag() { } public int doStartTag() throws JspException { try { pageContext.getOut().print( “第一个标签,HelloTag !” ); }catch (IOException ioe){ throw new JspException( “Error : IOException while writing to the client” +ioe.getMessage()); } return SKIP_BODY; } public int doEndTag() throws JspException { return SKIP_PAGE; } public void release () { } public void setPageContex ( PageContext pageContext){ this.pageContext = pageContext ; } public void setParent (Tag parent) { this.parent = parent ; } 38 public Tag getParent() { return parent ; } } 在编写好自定制标记的句柄类之后,我们就可以按照前面章节所介绍的字定制标记描述 符文件(TLD),并一同打包成为一个 jar 文件部署我们刚刚编写好的自定制标记句柄类。 然后在 web.xml 中定义,然后我们就可以在 JSP 中使用自定制标记了。 在 TLD 中定义如: . hello myTag.HelloTag empty Hello Testing . 在 web.xml 中定义了 myTag.tld /WEB-INF/lib/myTag-tags.jar 注:我们写的 java 类和 TLD 文件打包成为 myTag-tags.jar。 而 JSP 代码如下: <%@ taglib uri= ”myTag.tld” prefix= “test” %> Hello Test Tags

这是测试的自定制标记 Hello Tag

标记属性的使用 自定制的标记还可以定义任意数目的属性,那么开发人员可以在 JSP 页面中进行设置, 39 这些属性信息会传递到标记句柄类中,根据传递来的信息进行相应的动作。 首先属性应该在 TLD 中,通过元素进行定义,定义包括属性名称和属性 的其他特征。标记句柄类需要针对这些属性实现 get 和 set 的方法,其方法定义与 JavaBeans 中针对属性的 get 和 set 方法类似。 例如:如果定义了一个名为 foo 的属性,标记句柄类需要提供下列的公共方法: public void setFoo(String f); public String getFoo(); JSP 引擎初试化标记句柄类之后,在执行 doStartTag( ) 之前,在针对该句柄类中的每一 个属性调用其相应的 set 方法。通常你只需要实现 set 方法来保存属性的值,这些值可以被 标记句柄类中的其他方法所调用。 自定义的脚本变量 标记句柄还可以引入新的脚本变量,在 JSP 页面中的各种范围下进行引用,脚本变量也 可以在其定义的范围内以一个不明确定义的对象那样使用,如同 JSP 语法中的 out、page 等 相似。 如果想使用自定义的脚本变量: 1. 首先在 TLD 中用元素中来定义,并且指明实现的 java 类,它应该继承 javax.servlet.jsp.tagext.TagExtraInfo。 例如:weblogic.taglib.session.ListTagExtraInfo 2. 然后编写 TagExtraInfo 类,例如: package weblogic.taglib.session; import javax.servlet.jsp.tagext.*; public class ListTagExtraInfo extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData data) { return new VariableInfo[] { new VariableInfo("username", "String", true, VariableInfo.NESTED), new VariableInfo("dob", "java.util.Date", true, VariableInfo.NESTED) }; } } 3. 然后通过 page context 来设置标记句柄类来初试化脚本变量的值。例如:下面的代码 可以在 doStartTag()方法中来初试化脚本变量的值: pageContext.setAttribute("name", nameStr); 40 pageContext.setAttribute("dob", bday); 其中第一个参数为脚本变量的名称,第二个参数为脚本变量的值,在上面的例子中我们 可以看到:nameStr 是一个类型为 String 的对象,bday 是一个为 Date 的对象。 另外,也可以通过 TagExtraInfo 类来访问直接这些变量,就象通过 useBean 来使用 javaBeans。 自定义标记库的新功能 J2EE1.2 规范对自定义标记库新定义了几种功能,如:在内容体标记中遍历和在内容体 标记内处理异常,以及标记库的校验类等,但目前 J2EE1.2 规范还没有最终定稿,所以有关 这些内容的定义还可能会发生改变,如果需要使用这些新功能,需要留意 J2EE1.2 规范的最 终稿。下面我们来简要的来介绍一下这几种新增功能: 1. 在内容体标记中遍历 如果一个标记实现了 javax.servlet.jsp.tagext.IterationTag 接口,它需要实现一个名为 doAfterBody( )方法,这允许你有条件的重新评估标记内的内容。如果 doAFterBody()返回 IterationTag.EVAL_BODY_AGAIN ,内容会被重新评估,如果 doAfterBody() 返回 Tag.SKIP_BODY,那么内容会被忽略并执行 doEndTag( )方法。 2. 在内容体标记内处理异常 当实现 javax.servlet.jsp.tagext.TryCatchFinally 接口的 doCatch( ) 和 doFinally( )方法后, 开发人员就可以捕获标记内抛出的异常信息,并进行相应的异常处理动作。 3. 标记库的校验类 标记库校验类是一个用户编写的 Java 类,通过该校验类你可以执行对 JSP 页面进行自 定义的校验。校验类可以将整个 JSP 页面作为一个输入流,通过校验类所设置的校验条件对 该数据流进行验证。 使用校验类通常的方法是在类中使用一个 XML 解析器通过 DTD(documents type definition)来校验 JSP 页面,校验类在页面翻译时(当 JSP 页面被翻译成 servlet 的时候)被 调用,当页面校验通过会返回空字符串。如果校验出错,则返回错误信息。一个校验类通常 是继承 javax.servlet.jsp.tagext.TagLibraryValidator 类。 在 TLD 中引用校验类,例如: myapp.tools.MyValidator WebLogic 的自定制标记的使用 BEA WebLogic 应用服务器提供了一系列的预先定制好的标记,供 Web 应用的设计和 开发人员在开发 JSP 页面的时候使用,它们是 cache、repeat 和 process 标记,这些标记打包 在一个名为:weblogic-tags.jar 的标记库中,这个 jar 文件还包括了用于处理这些标记的类和 标记库描述符(TLD)。另外 WebLogic 还提供了一组对 HTML FORM 中的字段进行验证 的标记,用户也可以根据这些的标记所提供的接口,增加满足用户自身所需的特殊验证功能 41 的标记。 下面我们对这些标记逐一的加以介绍: cache 标记 cache 标记允许将 HTML 中 body 标记内已经完成的工作存入缓存,它既支持数据输出 (数据传递)和输入数据(被计算的数据)。输出的缓存是将标记的内生成的内容存入缓存, 输入缓存保存标记内设定变量的值。 缓存使用 soft reference 方式保存,这样可以防止缓存系统使用过多的系统内存。但由于 HotSpot VM 和传统 VM 之间不兼容,当 WebLogic 服务器运行于 HotSpot VM 时候,soft reference 就不再被使用。 你可以通过设置 _cache_refresh 的值为 true 来强制指定范围内的缓存进行刷新。例如, 在 session 范围内刷新缓存: <% request.setAttribute (“_chache_refresh”,”true”); %> 如果需要所有缓存都需要刷新,那么将缓存设置为 application 范围。如果只刷新针对某 一用户的缓存,则将范围设置为 session。如果针对当前请求的缓存都被刷新,则设定 _cache_refresh 对象或者设定为一个参数或者包含在请求内。 标记指定的内容,在其每次显示的时候被刷新。在 标记之间的内容,只有缓存过期或者其属性被改变的时候被执行。 列表 3-1 cache 标记属性列表 标记属 性 是 否必须 缺省值 描述 timeout No -1 超时属性,以秒计算超时时间,当该时间 达到时,会刷新 cache 标记内的内容。如果你 希望使用其他的单位时间,而不是以秒设定, 那么可以通过在设定值后面添加指定的时间 单位,来设定超时间隔。这些时间单位后缀包 括: ms = 毫秒 s = 秒(缺省) m = 分钟 h = 小时 d = 天 Scope No application 指定缓存内的内容作用范围,包括:page、 request、session 、application。 多数的缓存应 用划分为 session 或者 application。 key no -- 其他附加的参数,用于指定标记内的值是 否加入到缓存中。关键字的值采用逗号分隔, 该属性的值是你希望用于保存到缓存中关键 字值的变量的名称。你还可以指定该关键字值 的作用范围范围。 例如:parameter.key | page.key | request.key | application.key | session.key 42 它缺省的搜索顺序按照前面所列的顺序 进行,每个命名的关键字可以象脚本一样在标 记中使用。 async no false 如果参数 async 设置为 true,缓存将被设 置为异步刷新。如果可能,初始化这个缓存的 用户可能会看到旧的数据。 name no -- 缓存中唯一的名称,用以使之在多个 JSP 之间共享。这个相同的缓冲区用于保存所有使 用该命名的缓存的页面保存数据。当缓存需要 共享时,该属性的设置就变得十分有意义了。 如果没有设置该属性,系统会分配给缓存一个 唯一的名字。建议你尽量避免使用人工的方式 计算标记的名称,采用关键字的功能可以一样 的使用缓存,被使用的名称一般是 weblogic.jsp.tags.CacheTag。加上 URI 加上一 个代表缓存页面中标记的自动生成的号码。 如果到达同一个 JSP 页面的 URI 不同,缺省设 置为缓存不共享,此时只要设定 name 属性, 即可实现共享。 size no -1 (无限) 对于使用带关键字的缓存,该参数表明入 口数量,缺省的对缓存的关键字的值没有限 制,改变一个已经使用的缓存的 size 属性的值, 并不会改变该缓存的大小。 vars no -- 除了将输出的数据进行缓存以外,你还可 以选择对需计算的数据进行缓存。这些指定的 变量也缓存的键所起的作用一致,该类型的缓 存称为输入缓存。 例如: process 标记 使用标签用来查询基于参数的流程控制。通过综合使用该标签的 4 个属性, 你可以选择标签之间的所执行的内容。Process 标签也可以声明 处理子任务执行的结果的过程。通过基于请求参数的值来指定条件,你可以选择在页面中是 否包含或者不包含 JSP 语法 列表 3-2 process 标记属性列表 标签属性 是否必须 描述 name 否 请求参数的名称 notname 否 请求参数的名称 value 否 请求参数的值 notvalue 否 请求参数的值 下例显示了如何使用 process 标签:
44 repeat 标记 使用标记来实现遍历不同的集合,包括 Enumerations, Iterators, Collections, 对象数组 , Vectors, ResultSets, ResultSetMetaData, 以及 Hashtable 的 key。也可以通过 count 属性执行一定次数的循环。 列表 3-3 repeat 标记属性列表 标记 属性 是 否必须 类型 描述 set 否 Object 对象集合包括: Enumerations Iterators Collections Arrays Vectors Result Sets Result Set MetaData Hashtable keys count 否 Int 在集合中遍历的次数。 Id 否 String 存储当前遍历对象的变量。 type 否 String 遍历对象返回结果对象的类型,缺省为对象, 该类型必须符合 java 代码规范。 下例为一个使用标记的例子。 "> <%= name %> <% Vector v = new Vector();%> Form 验证的标记 WebLogic JSP Form 校验的标记提供了一个便捷的方式来校验最终用户通过 HTML FORM 中的 text 类型输入的信息。使用 WebLogic JSP Form 校验的标记可以避免不必要和 重复的数据验证的代码。这些验证通过 WebLogic 提供的 JSP 个性化的标记来实现,它们可 以: 校验必须输入的字段是否填写(Required Field Validator class) 45 验证输入的文本是否符合语法表达(Regular Expression Validator class) 比较 Form 中的两个输入是否匹配(Compare Validator class) 通过你自己编写 Java 类来实现自定义的验证(Custom Validator class) WebLogic JSP Form 校验的标记包括: 当校验标记判断出某一个字段输入的数据不正确时,该页面会重新显示,同时需要重新 输入的字段会被通过文本或图片打上标记来提示用户。一旦 Form 正确填写,用户的浏览器 会显示验证标记所指向的一个新的页面。 1. 标记是所有校验标记的父标记,你需要在任何 HTML 和 JSP 代码之前打 开标记。并在标记之后放置。 它包含以下几个属性: name (可选的)用以保存所有由 JSP 页面中的所产生的校验错误信息的向 量变量的名称。其缺省的值为:errorVector,出错信息是由标记的 errorMessage 属性所定义的。 若要显示这些出错信息,使用标记,将该标记放置到页面上需要输出 该信息的位置。例如: 或者你也可以使用脚本来实现,例如: <% if (errorVector.size() >0 ) >{ for ( int i=0; i”); } } %> 这其中 errorVector 是向量变量的名称,它就是使用了标记的 name 属性。 当页面中存在多个 Form 时候,name 属性是必须的。 headerText 它定义了出错页面上所包含的一些信息。当页面产生错误时,如果你只希望使用该处的 文字,你需要使用脚本来实现。例如: <% if (summary.size () >0 ) { out.println ( headerText ); } %> 其中 summary 是标记定义的向量的名字。 redirectPage 如果校验成功,没有返回错误信息时,所跳转的页面的 URL。当在标记的 46 actions 属性中定义所跳转的 URL 时,该属性就不是必须的了。 注:不要使用设置 redirectPage 属性为包含标记的同一页面,这样你会生 成一个无限的循环,并产生 StackOverFlow 异常。 2. 标记与 HTML 中的
标记很相似,它定义了一个 HTML 页面的 form, 但同时它还可以通过使用 WebLogic JSP FORM 校验标记进行信息校验。你可以通过 name 属性来在一个页面中定义多个 FORM。它的属性包括: method GET 或者是 POST,在功能上与 HTML FORM 中的 action 属性相同 action 当校验成功,没有返回出错信息的时候,所要跳转到的页面的 URL,在系统执行时, 该属性标记的定义信息要优先于标记的 redirectPage 属性所定义的值,当页面 中包含多个 FORM 时特别有用。 注:与 redirectPage 类似,不要使之设定为包含标记的同一页面,这样你 会生成一个无限的循环,并产生 StackOverFlow 异常。 Name 在功能上,它与 HTML FORM 标记中的 name 属性一样,用于在页面中唯一标识 FORM。 特别是利用 JavaScript 脚本编程时,该属性十分有用。 3. 可以对 FORM 中的输入字段使用一个或者多个标记,例如:你想对一个 输入字段既希望该字段必须输入,又要判断是否满足一定语法规则,你可以使用两个 标记,一个采用 RequiredFieldValidator 类,另一个使用 RegExpValidator 类(因 为 Regular Expression Field Validator 认为用户的空白输入是合法的)。它包含以下几个属性: errorMessage 在标记中 name 定义的向量变量中所保存的一个字符串。 Expression 当使用 RegExpValidator 类时,进行计算的表达式,如果未使用该属性,则可以忽略该 属性。 fieldToValidate FORM 中需要进行校验的字段名称,它使用 HTML 标记中所定义的 name 属性。 validatorClass 执行校验逻辑功能的 java 类的名称,缺省的提供了三中校验类,你也可以使用自定义 的校验类来进行数据校验。 提供的三种校验的类为: weblogicx.jsp.tags.validators.RequiredFieldValidator 校验字段是否填写信息。 47 weblogicx.jsp.tags.validators.RegExpValidator 判断所填写的数据是否符合一定的语法规则。 注: 空白的值是合法的。 weblogicx.jsp.tags.validators.CompareValidator 比较两个输入字段是否包含相同的字符串,当使用该类时,在 fieldToValidate 属性设定 你所需要比较的两个字段名称。例如: fieldToValidate="field_1,field_2" 注: 若两个字段都是空的,该比较依然是合法的。 myPackage.myValidatorClass 自定义的校验类 使用自定义的校验类 如果 WebLogic 所提供的校验类上的校验功能不能满足业务的需要时,可以自己定制校 验类。 1. 首先需要继承 weblogicx.jsp.tags.validators.CustomizableAdapter 抽象类。 2. 然后实现其 validate ( ) 方法,在这个方法中,你需要做以下一些事情: 通过 ServletRequest 对象寻找需要校验的 FORM 中的字段,例如: String s1 = req.getParameter(“field_1”); 返回 true,如果该字段满足校验条件。 编译该类文件,并将文件放在 Web 应用的 WEB-INF/classes 目录下。 在标记中,通过设定 validatorClass 来使用自定义的校验类,例如: 最后我们给出一个使用校验标记的 JSP 例子: <%@ taglib uri="tagl" prefix="wl" %> <%@ taglib uri="input" prefix="input" %> Untitled Document <% if(summary.size() >0 ) { out.println("

" + headerText + "

"); } %> <% if (summary.size() > 0) { out.println("

Error Summary:

"); for (int i=0; i < summary.size(); i++) { out.println((String)summary.elementAt(i)); out.println("
"); } } %> User Name: This is a required field! 49

Password: This is a required field!

Re-enter Password: Passwords don't match.

50

3.3 Web Service 的应用 随着企业业务的发展,越来越多部门开发了自己的应用,这些应用在开发时并没有考虑 到相互间信息的交换,但随着业务的进一步拓展,这些原来相互独立的应用之间需要进行数 据交换,这在一个企业的内部是如此,而不同企业之间随着业务的往来,也需要不同企业之 间进行数据的交换,基于传统的 client/Server 体系结构开发的应用,由于 Client 端的不同, 而很难去调用其他不同应用所提供的数据信息。但是由于 Web 技术的发展,使得我们拥有 了进入不同业务系统的入口,真正实现针对不同客户端的单点入口则需要 Web Service 技术。 2.1 Web Service 技术基础 Web Service 是一个新的 Web 应用,它是一个自我包容、自我描述、模块化的应用, 可以被发布,定位寻找以及通过 Web 来调用。换言之,它是由一组协议、规范和网络设施 所组成,并通过 Web 相连接的设计,通过它可以访问其他可信任机构的功能服务。 一个 Web Services 平台使用一个称为 SOA(Service-Oriented Architecture)的组合模型, 这个架构模型相对于组件功能,更偏重于提供服务。SOA 的特征包括:可互操作性、服务 搜索和动态绑定,这也是 Web Services 的功能。 几乎所有任何逻辑形式的服务都可以通过 SOA 架构来构建,它提供了唯一的组件可以访问所有的应用服务。图 3- 10 演示 SOA 架构 的模型: 51 Service Provider Service Broker Service Requester 服务 描述 服务 描述 服务 Publish Bind Find WSDL WSDL 图 3-10 S OA 架构模型 我们看到在 SOA 架构中主要包含三个角色: Service Provider: 它提供服务的接口,提供访问者所需的业务服务。 Service Requester: 它用于查找服务,同时向服务提供者调用服务。 Service Broker: 它管理着一个信息存储库,用于保存服务提供者和其所提供服务的信 息。这些信息包括:1) 商业数据,例如服务提供者的名称、描述和联系方式; 2)用于描述 实际调用策略、业务过程和绑定信息的数据。一个服务的中介通常除了拥有信息保存功能之 外,它还提供了智能查找功能和业务分类数据信息。 在 SOA 架构中存在着三种操作: Publish 服务提供者将自身的服务信息发布给服务中介,执行该操作的通常是标准化 组织、软件提供商和开发人员。 Find 服务请求者通过服务中介来查找自身所需的相应的服务,该操作执行频率最高。 Bind 服务请求者利用服务中介处获取的信息来绑定一个实际的服务。 对于一个简单的 Web Services 服务来说,它需要有各种技术要求,包括 XML 技术、很 多商业协议,如:ebXML, TRP, BTP, RossettaNet 等等,但其基础主要有:SOAP、WSDL 和 UDDI,下面我们逐一介绍 SOAP SOAP 是简单对象访问协议(simple Object Access Protocol),客户端是通过 SOAP 协 议来调用 Web Services。SOAP 定义了以 XML 格式来请求业务方法的调用,它可以支持运 行于一系列低层的协议,如:HTTP(S),SMTP 等。使用 XML,是因为其与语言无关,并具 有很高的可扩展性的优势,而支持 HTTP 则是因为任何基于 Internet 的系统都是可以通过套 接字来相互间通讯,但 HTTP 则具有简单方便,和任何系统都有很好的互操作性,另外还可 以穿越防火墙。 SOAP 是一个轻量极的协议,并且便于理解,还可以方便操作。 52 SOAP 指明了如何管理各种方式的调用,以及参数信息如何封装。通常,一个 SOAP 信 封包含着可选的头标记,以及内容,并以 HTTP POST 方式传递到一个 HTTP 服务器上,当 然 SOAP 也可以通过 SMTP 来实现。SOAP 支持消息传递和 RPC 调用两种语法。 下面就是一个 SOAP 调用的例子: POST /Weather HTTP1.1 Host: 10.128.3.114:7001 Content-Type: text/xml; charset="utf-8" SOAPAction: "SOME-URI" 310000 上例中客户端通过提供一个 zip code 去查询当地的气温信息。 WSDL WSDL 是 Web Services Description Language 的缩写,它定义了用于描述网络服务 的 XML 文档,包括:服务的接口,语法,Web Service 调用的处理动作定义等等. 例如: 53 todo 上例中的 WSDL 包含以下的主要信息: 接收的消息格式和其描述,在元素中定义,它通过内置的 XML 格 式定义解析。 消息传递的语法。在 元素中定义,如:request-only request-response response-only 等 指定的消息编码格式,通过传输协议的编码设定,在元素中 在元素中定义的服务的终点(一个 URL) WSDL 的信息模型如下图所示: 54 图 3-11 WSDL 信息模型 WSDL 通常和 UDDI 一起作为接口描述格式而被提及,UDDI 通常指存储 WSDL 的位 置,而且 UDDI 没有限制它所存储的描述文件的格式,它可以是 WSDL,面向人参考的 WEB 页面或者是 e_mail 地址列表等。 UDDI UDDI 是 Universal Description, Discovery and Intergration 的简称,它是一组基于 Web 的信息存储空间,并对外提供服务信息,你可以把它设想为在基于 Web 领域提供服务的 DNS 服务器,使用者可以通过它来查找想要访问的服务。 它类似于一个文件系统,存储了服务的相关信息(以 WSDL 格式),它可以提供多种 检索的方式,如基于业务方式、服务类型以及主题方式等,这样便于开发人员来查询 UDDI 上所注册的服务信息。UDDI 通常使用 SOAP 消息格式来发布、编辑、流览和检索信息。当 然它也支持采用其他的 XML 格式来进行相应的操作。 它描述了服务信息 who, what, where 以及 how Bindi Abstr Concr Serv PortMessag Operatio P Me Me Operatio Messag 55 businessEntity 关于发布服务的信息提供 者的信息。 tModel: 描述服务或者分类的规范 WHO: 名称 标识 联系信息 WHAT: 分类 代码 提供的服务 WHERE: 提供服务位置 HTTP/FTP/SMTP HOW: 服务定义的规范 WSDL binding Template 提供了服务入口点,构建 指示信息 businessService 描述了某一厂商所提供的技术服 务信息。 图 3-12 UDDI 模型 2.2 WebLogic 的 Web Service 的实现 WebLogic 提供了两种形式的 Web Services 服务,一种是基于 RPC 调用的,还有一种 是基于消息传递的方式。同时它也可以继续作为客户端,向其他 Web Service 的提供者请求 服务。 图 3-13 WebLogic WebService 实现 RPC 调用形式的 Web Service 如图 3-14 所示,在 WebLogic 中它是通过调用一个 stateless S OAP S WebL ogic “Thin” Java client S OAP WebLogic J2 EE A Other clients S OAP S OAP Cl Other WebL ogic Apps S OAP Other vendor apps S OAP WebLogic J2EE A HT H 56 EJB 来实现的,对客户端应用而言表现如一个远程对象。 客户端和 RPC 形式的 Web Service 交互集中于服务指定的接口,当客户端调用 Web Service,客户端会发送参数给 Web Service,Web Service 会执行所调用的方法,然后将返回 值传递回客户端。由于这种客户端和 Web Service 之间的来回对话,因此此种形式的 Web Service 紧密偶合,很象传统的远程方法调用,如 RMI 或者 DCOM。 图 3-14 Web Service 的 RPC 方式实现 基于消息的 Web Service 则利用 JMS 的消息侦听机制来实现,如 Message-driven bean, 但必须指定 JMS 的消息目的地。 基于消息的 Web Service 是一种送偶合的形式,并且是文本驱动的,而无须 与服务指定的接口相关。当客户端调用基于消息的 Web service时,客户端通常 是发送整个文档而不是发送一些参数,如购买订单。Web service 接收到整个文 档并进行处理,它可能会产生返回值或者没有返回值, 由于请求和响应之间没 有紧密的偶合,所以基于消息的 Web Service在客户端和服务器端提供的一种解 偶模式。 基于消息的是异步的,一个拥护调用 Web Service 并不需要等待结果就可以 继续进行其他操作。而从 Web Service产生的响应可能会一个小时或者几天才发 送给客户端。客户端利用基于消息的 Web Service发送或者接收整个,也可以两 个任务都执行。 S OAP H S OAP Messag e C Web Services-Enabled Server H Me Prod S OAP H S OAP Stat eless Web Services-Enabled Server Other J2EE C H invoke( RESPON 57 图 3-15 Web Service 的 Message 方式实现 Java 客户端的开发 WebLogic 提供了用于开发 Web Service 客户端的开发包,这个包是在将 Web Service 部 署到 WebLogic 时自动生成的,无须开发人员自行打包。WebLogic 支持两种 Java 客户端开 发方式: 静态的客户端方式,客户端明确的指明组成 Web Service 的 EJB 或者 JavaBean 接口类, 这类的客户端应用是类型安全的,并且也是 BEA 所推荐使用的方式,另外静态的客户端也 不包含任何 Web Logic 的特殊 java 的代码 动态的客户端方式,它不明确指明组成 Web Service 的 EJB 接口,是通过 一个代理来 去调用。下面我们分别介绍以下这两种客户端的编写。 首先是通过 URL 去获得提供 Web Service 的 WSDL 访问一个存储于 WebLogic 的 Web Service 的 URL 格式为: [protocol]://[host]:[port][context][WSname][WSname].wsdl 其中 protocol 缺省为 HTTP, host 指向提供 Web Service 服务的主机 port 指提供 Web Service 服务 WebLogic 服务器实例所用的端口号 context 指保存 Web Service 服务的上下文 WSname: Web service 的名称。 例如:http://www.myHost.com:7001/myContext/statelessSession.WeatherHome/statelessSess ion.WeatherHome.wsdl Java 静态客户端开发 该例中我们使用 http://www.myhost.com:7001/myContext/statelessSession/statelessSession.wsdl 来获得 Web Service 的 WSDL, 静态的调用 WebLogic 上的 Web Service 的 java 代码与调用 EJB 的远程方法调用的客户 端 java 代码相似。 首先下载该 Web Service 所提供的客户端开发文件(*.jar),配置 classpath,然后初试 化,使之可以和 Web Service 交互。 Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.soap.http.SoapInitialContextFactory"); h.put("weblogic.soap.wsdl.interface", Trader.class.getName() ); Context context = new InitialContext(h); Trader service = (Trader)context.lookup( "http://www.myHost.com:7001/myContext/statelessSession/state lessSession.wsdl" ); 假设 Trader 是 EJB 的公共接口,通过 context.lookup()方法来形成一个远程对象,成功 后就可以执行该 Web Service 所提供的服务了 TradeResult result = (TradeResult)service.buy( "BEAS", 100 ); 58 Buy 方法是 Trader EJB 所提供的,其返回值是 TraderResult JavaBean 对象,而要查看 Trader EJB 的公共方法,或者检索返回的 WSDL 文件,或者将下载的客户端 jar 文件解包, 然后用 javap 工具查看 Java 动态客户端编写 该例中我们使用 http://www.myhost.com:7001/myContext/statelessSession/statelessSession.wsdl 来获得 Web Service 的 WSDL, 首先下载该 Web Service 所提供的客户端开发文件(*.jar),配置 classpath,然后初试 化,使之可以和 Web Service 交互。 Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.soap.http.SoapInitialContextFactory"); Context context = new InitialContext(h); WebServiceProxy proxy = (WebServiceProxy)context.lookup( "http://www.myHost.com:7001/myContext/statelessSession/state lessSession.wsdl" ); context.lookup() 返回 WebServiceProxy 对象而指定的 Trader 对象,通过 WebServiceProxy 对象可以代表任何 EJB 对象 然后通过执行 EJB 的公共方法来调用 Web service 的操作: SoapMethod method = proxy.getMethod( "buy" ); TradeResult result = (TradeResult)method.invoke( new Object[]{ "BEAS", new Integer(100) } ); 其他客户端的开发 由于 Web Service 技术的引入,使得其他非 Java 的客户端也以方便的调用 WebLogic 所 提供的服务。我们以一个 VB 的客户端为例来说明。如图所示:通过 VB 中的一个 Form 来 调用 WebLogic 上所提供的 Web Service,这样对于已有的系统,可以无须大规模的结构修 改就可以使用 WebLogic 服务器所提供的很多新的功能和服务。同时也为用户在系统设计时 客户端的选择提供了更多的选择余地。 59 首先定义 SoapClient 同时执行初试化动作查找所需的 Web Service Private Client As SoapClient Private Sub Connect() Set Client = New SoapClient Client.mssoapinit "http://localhost:7001/weather/statelessSession.WeatherHome/statelessSession.WeatherHome.wsd l", "Weather", "WeatherPort" End Sub 然后就可以调用相应的 Web Service 了 Private Sub getTemperature_Click() On Error GoTo ErrorHandler Connect Text1.Text = CStr(Client.getTemp(ZipCode.Text)) Exit Sub ErrorHandler: MsgBox Client.faultstring, vbExclamation End Sub 3.4 个性化设计 简单地说,个性化设计就是为特定的用户指定特定的 WEB 内容和应用,即 WEB 内 容开发人员基于某些条件为特定的个人或用户组而裁剪信息或一个应用。它通过以下步骤来 实现:首先收集和存储站点访问者的信息,然后对信息做分析,在分析的基础上在适当的时 间将适当的内容提交给每个访问者。 3.1 为什么要个性化设计 为什么需要个性化的设计呢?一个 Web 应用的服务提供者需要考虑到应用的不同使用 者之间对于这个应用的要求是有所区别的,不象基于 Client/Server 的应用,用户通过菜单的 选择来进入其相对应的服务,而基于浏览器的应用中,虽然也是可以利用菜单来定制不同用 户的服务,但这样无法充分发挥浏览器所具有的可以显示更多信息的功能优势,而丰富的显 示信息如果只是简单的罗列,会造成用户无法定位其自身所需要的服务,根据不同的用户的 身份不同,可以选择不同的显示风格和信息,可以更好的满足使用者的特殊需求,同时也不 会因为个性化的要求而大幅度增加系统开发的成本。 在将一个 WEB 应用中的信息个性化时,需要区分每个访问者,这主要有两个基本原 因,一是为了匹配内容(信息),二是为了提交特定的信息和应用程序给访问者并在所能提供 的服务的基础上相应改变应用的处理流程。 个性化的应用设计通常有两种需求来驱动,一个是用户自身的需要,允许用户选择与之 相关的内容并很好的组织这些内容。另一个是业务上的需要,它允许业务逻辑根据使用人员 的不同需求定制、组织和传递相应的内容。 对于用户自身,他对于一个基于 Web 的应用而言,有着下列的需要: 内容选择 界面显示模式 60 布局的个性化 而对于服务的提供者而言,满足用户个性化的需要,可以更好的定位用户的实际需求, 这样为不同的用户提供专门的服务,而同时不需要增加系统开发的工作量。 3.2 如何应用个性化 一个个性化的 Web 应用的解决方案中主要包括以下组成部分: 1.概况表:站点的用户,包含每个用户的属性,组及层次性; 2.内容模型:产品、文章和程序等; 3.匹配技术:用户概况表、规则、建议或其组合; 4.对内容资源库的填充; 5.对个性化效果的反馈。 JSP布局设置 <..> <..> 个性化 信息显示 Portlet 图 3-16 个性化应用页面布局 如图 3-16 所示,一个个性化的 WEB 应用,其用户显示界面会划分为多个部分,每个部 分可以根据不同的个性化规则针对不同的用户显示不同的内容。每一块可以称为 portlet,而 整体的显示则通过页面的有效布局来划分,在设计页面的时候,首先利用相关工具设计页面 整体的布局(如图 3-???所示),然后根据应用的实际业务需要,设计每一个 portlet 需要显 示的内容,有关内容的定制和内容显示的规则定义需要利用相关的内容管理工具和规则定义 工具实现。 61 <%@ taglib uri='layout.tld' prefix='layout' %>
图 3-17 个性化布局设计 而对于一个 WEB 应用,其个性化主要包括基于以下几种类型进行分类: 1.基于用户概况(User Profile) 基于用户概况表或简单的过滤主要用于在预定义的组或用户概况表的基础上显示特定 内容。 例如,当某用户在一门户网站注册后,网站选择特定的新闻来满足他/她对新闻预定 的需要。 2.基于规则(Rule) 基于预定义的商业规则来显示特定内容。 3.基于建议(Recommendation) 基于某一特定用户的喜好和与他具有相似意向或目的用户的喜好的组合来显示特定内 容。它构建在以下两个基本原则之上:客户的喜好不是随机的;人们对某产品表现出的相同 口味使我们可以将此产品推荐给其他客户。 针对上面所陈述的几种个性化的应用类型,应该如何开发一个个性化的 WEB 应用 呢?这主要包括以下几个重要的步骤: a) 明确你的商业需求。一个应用的实际商业需求是什么,希望定位什么样的用户。 b) 定义你的用户和内容模型。需要什么样的概况信息来对访问者分类,需要什么样的 内容类别来达到定位目的。许多应用一般是通过 HTML FORM 表格来获得用户需求和喜好, 输入表格中的信息既有很少变化的(如用户名和地址),又有需要随时更新的(如需求等)。 内容即 WEB 页上显示的格式化数据,当对一个应用实施个性化时,不需要对页面中所有 元素都实行定制;而且,尽管每个客户是唯一的,你也不需要实现为每个客户显示唯一的信 息,用户应该被分类或分组。 c) 选择最适合你的个性化策略的匹配方法。如何知道你该选择哪种个性化技术?不可 能用一种技术来满足所有的商业需求。对大多数应用来说,不管它的大小,基于用户概况表 和规则的个性化技术是比较容易实现的。而较大的应用使用建议技术则最有效。当一个应用 已建立起较大的用户群时,可将当前用户的喜好和那些与他具有相似意向或目的用户的喜好 62 有效地结合起来以提供建议。 d) 设计页面的布局。JSP 页面可以包含 JavaBean 以显示规则或建议返回的查询结果。 开发人员通常利用个性化组件来构建个性化的应用,它可以包含一个由 JSP portlet 组成的 portal 实例,一组传统的 JSP 页面和 Servlet,以及直接访问 EJB 的代码。 e) 开发实现预定义的商业规则。一般通过特定的开发工具完成。 f) 实施整个应用 3.3 WebLogic 个性化设计实现 为了简化开发人员开发 WEB 应用的工作量,WebLogic 提供了一组开发 WEB 应用的组 件工具,开发人员可以利用这组工具快速的开发 WEB 应用。而其中,WebLogic Personalization Server 则是专门用于个性化应用开发的工具组件。 WebLogic Personalization 服务器架构 WebLogic Personalization Server (WLPS) 运行架构是为支持一系列个性化的应用而设计 的,这些应用可以利用 portal/portlet 结构来构建,也可以利用 Advisor 所提供的标记库和 EJB, 或者 WLPS 所提供的其他服务器端组件来构建。下图演示了 WLPS 中的各个组件之间的关 系: 图 3-18 WebLogic Personalization Server 架构 从上面的架构图中我们可以看到,WLPS 主要包含以下几个功能模块: 1. Advisor BEA WebLogic 个性化服务器中提供建议和推荐内容的一项服务,它定义了个性化应用 中最普遍使用的操作的基础接口。它通过标记或者单一的 EJB session bean 来使用嵌入式的 规则引擎,以此提供内容个性化的功能。规则引擎将用户分类并创建一个对内容数据库的动 态查询,然后返回针对当前用户的个性化内容。Advisor 能检索到任意类型的内容并用 JSP 63 或 Servlet 显示出来。它使用了基础类库、用户管理、规则服务和内容管理组件。 2. 内容检索和内容管理 内容检索通过 JSP 标记和 EJB 存取内容,内容管理标志查询内容数据库并返回内容 对象集。内容管理是一个创建、分类并将内容在应用中具体表现出来的一个过程,这通常涉 及创建和分类之间的工作流协调问题,并需要一定的搜索能力。 3. 规则和规则管理 规则在用户和将要提交的内容之间提供线索,它总是围绕着特定的商业逻辑,为了提交 个性化内容,规则管理工具提供编辑、部署和运行时服务。这些个性化部件使用商业规则来 为用户或用户组匹配合适的内容。开发人员可以定义的具有缺省值的命名属性,特性集将相 关的特性分组。例如,一个于健康相关的特性集可能包括年龄、身高、体重和是否患糖尿病 等。 4. 用户和组管理 用户管理将与用户相关的企业数据和用户的概况结合起来。这个过程包括映射预先存在 的数据和为个性化属性定义模式。它由 WebLogic 个性化服务器的用户管理管理工具集来 完成此项任务。用户的访问可以是JSP 标记或者由EJB 对象直接访问。一个统一的用户profile 可以是直接由开发人员设计。或者扩展了 User 这个 EJB 对象,同时还应提供字定制的数据 源以访问用户其他的属性值。 5. Portals and Portlets Portal 为 WEB 站点开发人员、组管理员和真正的最终用户提供 HTML 形式的窗口工 具集,以进行个性化、定制和考虑一个站点的布局、外观和内容。如果客户选择使用 Portal 产品,他们将用 JSP 来开发 Portlets,后者是一些具有信息、内容和应用服务的较小窗口, 它们可以被最小最大化。 6. 基础类库和工具集 基础类库提供了一组工具来帮助 JSP 和 JAVA 开发人员使用 WLPS 来开发个性化的应 用。工具集包括开发中可以使用的 JSP 文件和 java 类,通过这些工具可以加快开发人员来 实现个性化的功能。 利用 Advisor 开发个性化应用 内容的个性化允许 WEB 的开发人员为用户定制应用,基于通过用户信息,请求数据, 会话信息,Advisor 可以协调个性化的内容传递给最终用户。 Advisor 传递内容到一个个性化的应用中,是基于一组规则和用户信息的。它可以从一 个文档管理系统中获得任何内容信息然后以 JSP 的形式显现。Advisor 将系统中的所有服务 和组件组合起来来传递个性化的内容。Advisor 组件包括一个 JSP 标记库 和一个 Advisor EJB (stateless session bean),通过这些组件 Advisor 可以访问 WLPS 的核心服务: 用户信息管理 规则管理 内容管理 基础类库平台 标记库和 session bean 包含个性化的逻辑来访问这些服务,排列个性化的动作,以及返 回个性化的内容,同时你也可以编写自己的 adivslets,并通过你创建的 JSP 标记来访问它们。 这种设计架构允许 JSP 开发人员通过使用 Advisor JSP 标记来使用个性化的服务。另外 Java 开发人员也可以公共 Advisor bean 接口访问底层的 EJB 除了提供个性化应用中的内容以外,Advisor 还提供了用户分类的信息。例如,一个应 64 用可以向 Advisor 查询,基于预先定义的规则,当前用户是否是首要用户还是普通用户,并 根据这些信息执行相应的动作。Advisor 通过搜集用户自身信息来完成分类,并将这些信息 传递给规则管理器。. 使用 JSP 标记. 开发人员在开发一些页面时,会发现使用 JSP 标记来构建时非常有效, 这些标记基于用户的分类提供了有关内容显示的开关方式,基于静态的查询返回相应的内 容,以及基于执行内容查询的规则来匹配与用户相对应的内容,执行这些动作的标记包括: , 和 . 使用 Advisor session bean. 页面或者应用的开发人员可能需要直接使用 Advisor session bean,Advisor session beans 同样的提供了基于用户分类的内容现时开关方式,基于静态的 查询返回相应的内容,以及基于执行内容查询的规则来匹配与用户相对应的内容 Advisor 是一个 stateless session EJB 和一个含有 getAdvice 方法的简单接口,getAdvice 方法返回 Advice 对象,该对象包含了从个性化服务返回的详细结果信息。而 调用 getAdvice 方法的参数是一个包含一组 name-value 对的 AdviceRequest 对象,它定义了输入到 Advisor 中的信息。AdviceRequest 拥有一个类似于 HttpSession 对象的接口,并允许预先定义和自行 定制储存的参数信息。 每一个传入的 AdviceRequest 具有一个与之相关的 URI, Advisor 使用 URI 前缀(在逗 号之前的部分)通过 AdvisletRegistry 来查找 Advislet 。 Advislets 通常是一个简单的 java 类,它实现了个性化的一些功能,例如用户管理和内容反馈等,而 AdvisletRegistry 则维护 着所部署的 Advislet 实例与 URI 前缀之间的映射信息。 图 3-18 Advisor 的架构 利用 Advisor JSP 标记来构建个性化的应用 Advisor 提供了三个 JSP 标记来协助开发人员创建个性化的应用,这些标记为 JSP 提供 了 Advisor session bean 的一个视图,并允许开发人员通过编写页面而非 java 代码来获取个 性化的数据信息。 为了使用这些标记,你需要在 JSP 页面中利用 page 指令进行如下的设置: 65 <%@ page extends="com.beasys.commerce.axiom.p13n.jsp.P13NJspBase" %> Advisor 所提供的三个 JSP 标记包括: 标记会根据当前所执行的分类规则的执行结果来判断是否将用户提供的内容 打开或者关闭,如果返回结果为 true,它会将内容打开,否则则关闭。 系统会打开插入到 标记之间的内容,这些内容可以是任何合法的 JSP 元素,包括 HTML 标记,其他的 JSP 标记,如果返回结果为 false,系统会忽略标记之间的内容。 标记提供了内容属性以用于在内容管理器中检索,它会返回一个包含 内容对象的数组,开发人员可以以此来进行相应的操作。 标记则建议显示的内容,特别是用户信息满足内容选择中关于用户 分类的条件时。 当用户匹配,系统会执行规则中所定义的内容检索并返回相应的内容到 JSP 页面中。 下面我们分别对这三种标记加以介绍, 标记 标记会依据分类规则执行的结果来判断是否显示提供给用户的内容信息,如果 分类规则返回为 true,则显示有关内容,如果返回 false,则不显示这些内容。 注: 规则是在 BEA E-Business Control Center 软件中建立的.它是一个图形化的工具,允 许业务分析人员来定制自身的分类规则。由于业务分析人员并不会将规则的有关信息对外发 布,在外部看到的分类规则是"customer segmentation." 有关 BEA E-Business Control Center 的使用以及规则分类的信息请参见 BEA 相关产品的介绍。 例如: 下例会执行 PremierCustomer 分类规则并对符合首要用户条件的用户显示有关输出信 息 <%@ taglib uri="pz.tld" prefix="pz" %> . .

请选择我们新的首要客户奖励计划

提供了内容的属性信息,利用这些信息,内容管理器会检索有关的 内容。它的返回值是包含内容对象的一个数组。 例如: 下例会在内容管理系统中执行一个查询,用以寻找所有作者属性是” Hemmingway”的内 容,然后显示搜索到的文档标题。 <%@ taglib uri="pz.tld" prefix="pz" %> <%@ page import="com.beasys.commerce.content.ContentHelper"%> . .

    66
  • The document title is:
标记则建议显示的内容,特别是用户信息满足内容选择中关于用户 分类的条件时。 当用户匹配,系统会执行规则中所定义的内容检索并返回相应的内容到 JSP 页面中。 例如: 下例中,页面会向 Advisor 请求与首要用户有关的内容,然后显示结果的文档标题。 <%@ taglib uri="pz.tld" prefix="pz" %> . .
  • The document title is:
另外也可以利用 Advisor Session Bean 来构建个性化的应用,Advisor Session Bean 提供 了一系列的 API 供开发人员使用,它提供了相对于使用 JSP 标记的另一种方法来调用个性 化服务。 它与其他 EJB 客户端调用 EJB 服务的使用方法类似,在这里就不再加以介绍了。 3.5 表示层应用设计模式 对于一个 WEB 应用的开发而言,需要遵循一定的模式进行,这样才能有利于团队合作 开发,充分发挥整个团队的力量,同时也根据不同人员的职责进行合理的分工。 4.1 JSP 设计模式简介 早期的 JSP 设计中,存在有两种设计模式,它称为 JSP 模式一和 JSP 模式二架构,它 们之间的主要区别在于处理大量请求时的形式不同。在模式一中(参见图 3-19),JSP 页面 单独负责处理用户请求,然后将产生的响应返回给客户端,它也存在着将显示逻辑和业务分 开,数据的读取采用了 java Beans.尽管模式一的应用很适合简单的应用,但它不适合复杂的 67 系统应用。无限制的使用该模式进行开发,会造成 JSP 页面中会嵌入大量的 JSP 脚本和 JAVA 代码,特别是页面要处理大量的请求数据的时候。这对 JAVA 的开发人员来说可能不会有太 多的问题,但对于大系统中的 JSP 设计人员而言是一个繁重的任务。特别是在团队开发的过 程中会引起维护和开发中的问题。 浏 览 器 JSP JavaBean Request Response 数据库 应用服务器 其他企业应用 /数据源 1 4 2 3 图 3-19 JSP 模式一 而模式二的架构,参见图 3-20,是引入了面向对象的开发的思想(在后面的章节我们 会详细的介绍基于 MVC 架构来构建表示层的应用)。它采用了一种综合 JSP 和 Servlet 技 术,并利用这两种技术的,来实现客户请求的服务。它使用 JSP 来产生用户界面接口,而 Servlet 则主要负责执行面向过程的任务,同时 Servlet 还作为一个控制器,负责管理用户发 送来的请求,生成相应的 javaBean 处理实际的逻辑,然后根据执行结果产生相应的 JSP 页 面返回给客户端。通常情况下,在 JSP 页面中是不包含重要的商业逻辑的处理,它接收控制 器发送来的信息以及对象,并产生相应的结果。对于系统复杂的应用而言,采用模式二来构 建会比模式一具有不可言喻的优势。 68 浏 览 器 控制器 Servlet 模型 Java Bean Request Response 应用服务器 其他企业应用 /数据源 数据库 视图 JSP 1 5 3 2 4 图 3-20 JSP 模式二 4.2 基于 MVC 的设计模式 4.2.1 MVC 架构 对于一个企业的应用而言,它的应用可能存在多种客户端,同一个业务业务应用数据可 能需要以不同的视图方式表达,例如 HTML,WML,JFC/SWING 或者是 XML,而同时这 些不同的表达视图都有可能来更新业务数据,因此在构建系统应用的时候需要寻找一种有效 的途径来支持多种信息展现形式而同时又不影响业务核心的组件功能的修改。而通过 Model-View-Controller 模型来构建 J2EE 应用,可以将信息展现功能与业务控制功能分离, 这种分离可以使得系统支持不同的客户端更加容易的来访问系统所提供的服务,同时也方便 整个系统的实施、测试和维护。 在 MVC 设计模式中,应用数据流程是由一个中央控制器来控制,该控制器将用户发送 来的请求转发给相应的处理者,该处理者就称为 Model。而控制器在用户请求与 Model 之间 则象一个代理,同样的控制器也将模型所执行的动作结果与相对应的视图匹配。在一个独立 的 GUI 客户端,用户的交互可能是点击按钮或者选择菜单;而在 WEB 应用中,则表现为以 GET 或者 POST 方式发送来的 HTTP 请求。模型所执行的动作包括激活业务过程或者改变 模型的状态信息。基于用户的交互和模型返回的结果,控制器会选择相应的视图来提供响应。 模型通常代表或者是封装了应用的商业逻辑以及状态信息。模型代表了实际业务应用的 过程的模型。 视图主要用于表现模型所提供的内容,视图指定数据如何被显示,而这些数据则是通过 模型来提供。当模型改变时,系统通过视图来保证信息显示的一致性。它可以通过“推”模 式-- 视图注册到模型中,当模型改变时会通知注册的视图;或者“拉”模式-- 当需要获取 最新数据时,视图负责调用模型。 69 视 图 控制器模 型 JSP页面 以及其他组件 EJB Session Bean 或者其他控制类 Servlet 图 3- 21 WEB 应用的 MVC 模型 4.4.2 基于 MVC 的表示层设计 对于一个基于 Web 的应用而言,按照 MVC 方式开发的架构,它应包含至少三个组件, 一个 Servlet 来控制用户请求(控制器), 而 JSP、HTML 和 XML 作为信息展现(视图), 而具体的应用逻辑,可以是 JavaBeans 或者 EJB 模块(模型)。其逻辑结构如图 3-22 70 前置 的组件 请求处理 表示层 的控制器 JavaBeans 组件 表示层 HTTP请求 数据视图 应用层 模型数据 JavaBeans 组件 JavaBeans 组件 事件响应 模型更新提 示 图 3-22 表示层 MVC 的逻辑架构 控制器组件构建 控制器负责绑定 HTTP 请求,并根据请求的不同转发给系统中其他的对象进行处理,初 始时,该控制器将所有的映射信息读入,这些映射信息可以存储在配置文件中或者存储在数 据库中,然后它将信息转发给相应的展现模块来处理信息显示。 控制器利用其保存的映射信息将 HTTP 请求转发给相应的应用部件,一个映射至少需要 包括一个请求的路径和该请求所触发的对象动作,这个动作可以处理用户的请求同时生成相 应的响应反馈回客户端(通常是浏览器),或者它可以指明控制流程,将该请求转发给其他 的对象的动作。例如:一个用户登录的动作,如果成功它会将控制流程转发给显示主菜单的 动作。 执行动作的这些对象与应用的控制器相连接,当将控制信息转发时,一个对象可以直接 或者间接的转发一个或者多个共享的对象,这其中包括 JavaBeans,XML 文本对象。 系统处理请求的时序模型如图 3-23,ServletController 实际是用户访问系统的初始入口 点,它负责处理请求,包括调用授权和安全校验服务,解析请求的动作,然后传递给相应的 业务逻辑模块,同时根据响应结果调用相应的视图模块,同时还要负责出错处理,管理内容 生成的策略等工作。以一个用户请求为例,首先,Controller 通过 RequestProcessor 来解析 71 HTTPRequest 对象信息,然后调用 RequestDispatcher 寻找对应的动作执行类(Helper),通 过它来获取相应的业务逻辑信息,然后再调用相应的视图。在 J2EE 应用架构中,表示层中 的 Controller 是通过一个 Servlet 来实现控制功能的。RequestProcessor 是一个普通(plain) java 类,其主要功能就是解析 HTTPRequest 对象,返回该请求的具体信息,包括:请求的 URI, 动作是更新数据还是增加新的订单,以及确定执行动作的所需参数等,RequestDispatcher 是 一个将请求的 URI 和动作请求信息对应到相应的执行业务逻辑的动作类,它首先是读取映 射表,然后根据传递来的参数判断执行哪一个业务动作,这个映射表课时可以是保存在配置 文件中,也可以是保存在数据库中。映射表的信息可以在 ControllerServlet 初试化的时候进 行加载,也就是在执行 init()方法的时候,以 HashMap 的形式读入,它可以保存在 ServletContext 对象中,这样它所提供的信息在整个 WEB 应用中全局共享。 Client JSP ControllerServlet RequestProcessor RequestDispatcher View BusinessServiceHelper 1. send Request 1.1. analyze the request 2. dispath Request 2.1. retrive content 2.1.1. get data 3. dispatch info 3.1. get property 图 3-23 控制器处理的时序图 编写控制组件的主要任务包括: 设计和编写一个响应和解析请求的类(RequerstProcessor),它用于接收所有的逻辑请 求,并对其进行解析,分析请求的数据。 设计和编写一个请求和业务动作之间映射的类(RequestDispatcher),它用于定义针对 每个请求所对应业务逻辑动作和其他有关信息 编写请求到动作类的映射配置文件,例如 RequestMapping.xml,在该配置文件中配置请 求的 URI 信息,请求的动作信息,以及执行该 URI 下某一动作的具体的动作类或者所触发 的组件服务等。 编写 ControllerServlet,来实现控制器的功能 配置 WEB 应用的配置描述符文件(web.xml),将 控 制 器 ControllerServlet 部署到 WEB 应用中。 72 模型:系统状态和应用的商业逻辑 在一个利用 MVC 设计方式构建的应用中,模型可以划分为两种:一种是系统内部的状 态,另一种是由于状态改变所引发的动作。从语法上来讲,我们可以把状态的信息想象为一 个名词,而动作想象为一个动词。通常一个应用内部的状态信息可以表示为一组 JavaBeans 或者是 Entity Beans,其属性则详细的表示了系统的状态信息。 大型的系统应用中,代表商业逻辑的动作通常是以一个方法的形式存在的,你可以在 JavaBeans 中调用来维护状态信息。例如:当建立一个购物车的 JavaBeans 时,对每个用户, 信息按照 session 的范围来把保存,而其属性则代表了用户已经购买了的商品。同时 JavaBeans 还应提供一个 checkOut() 的方法,用来验证用户的信用卡信息,同时它还应提供从仓库提 取货物和运输的方法等。当然模型组件完全可以使用 EJB 来构建,通过 Session Beans 组件 提供系统业务动作处理,利用 Entity Beans 来表达系统的运行状态。有关 EJB 组件的应用开 发参见下一章节的介绍。 而小的应用系统中,可执行的动作信息可以包含在作为控制器的执行动作类的代码中, 当逻辑处理比较简单时,可以采用此种方式,但其商业逻辑就没有很高的可重用性。 视图模块构建 一个符合 J2EE 规范的 WEB 应用,采用 MVC 模式,视图组件一般使用 JSP 页面来实 现,用户所需的信息展现不仅依赖于 JSP,它还会结合 HTML 以及 XML 技术,使得信息展 现的更为丰富。 通常情况下是构建一个模板,根据实际动作的结果将动态的信息嵌入。在 JSP 的环境中 包含了一系列的动作标记,如标记,我们还可以使用自定义的标记和标记库。 除了 JSP 页面中的 action 标记以及用户自定义的标记以外,商业逻辑对象可能还会 产生自己相应的 HTML 或者 XML 信息,你可以通过 JSP 提供的标记将这些信 息在输出时引入。 我们看到在使用 JSP 构建视图时,它实际上需要很多相关的组件协同服务,因此我 们对这些组件进行封装,提供相应的 Helper 类来协助 JSP 视图实现信息展现工作。其工作 原理如图 3-???所示,一个客户的请求首先被 ControllerServlet 接收和处理,然后该控制器会 调用相应的视图显示(View),它是一个 JSP 页面,在 JSP 显示有关信息前,它会分别调 用 HelperOne 对象(一个 JavaBean)来获取某些业务数据,在 JSP 页面中是使用 加载 HelperOne 对象;HelperTwo 对象所提供的某些业务逻辑信息,在 JSP 页面中通过自定 制的标记执行。然后对 HelperOne 对象通过标记获得信息,或者利用自定 制标记得到数据信息。 73 Client ControllerServlet View HelperOne HelperTwo BusinessService 1. Request 1.1. Request View 1.1.1. Get Data 1.1.1.1. Get Data 1.1.2. Get Data 1.1.2.1. Get Data 2. Get Property 3. Get Attribute 图 3-24 View 和 Helper 工作时序图 而在实际的应用开发中,我们常常会发现,实现视图显示功能的 JSP 往往不仅仅是 一个页面,它可能包含多个部分,就如同在个性化设计当中,整个用户显示页面会被划分为 多个部分,这时我们在实现视图的功能时,需要考虑利用一定的设计模式。通过一个个实现 不同功能的 JSP 视图组合成我们所需要显示的视图。这样当业务发生改变时,整个视图结构 的改变,只需要将相应的一个视图模块进行修改或者将已有视图重新组合即可实现新的功 能,而无须对视图进行大量的修改。这些视图模块为我们构建不同的视图提供了可重用的组 件。下面我们举一个简单的例子来进行说明,如图 3-??? 所示。一个组合的视图可能包含如 下几个部分:Header,用于显示业务模块的配置信息,Content,用于显示业务模型的有关信 息,Footer 用于显示联系方式等相关信息。 74 Header.jsp Footer.jsp 通过其他组件 产生的动态 内容信息 执行动作的 Java Bean JDBC数据库 连接池 组件 数据库 图 3-25 组合视图逻辑模型 为了实现这个组合的视图,我们利用 CompositeView 来构建,而 ViewManager 来进行 管理各个视图模块,从下面的时序图中我们可以看到,CompositeView 通过 ViewManager 来管理各个视图组件,然后将这些组件组合成为一个合成的视图展现。它通过 JSP 规范中所 定义的来加载不同的视图组件,ViewManager 会根据不同的位置加载相应的视 图组件,包括:ContentView、HeaderView 和 FooterView。这些视图可以是 JSP 页面,也可 以是通过 JavaBean 或者自定制标记中所包含的视图。同样的 ContentView、HeaderView 和 FooterView 也可以依然是一个组合的视图模块。这样我们便可以利用已有的视图组件构建出 任何我们所需要的视图输出,满足不同用户对显示信息的需要。 75 ComopositeView ViewManager ContentView HeaderView FooterView 1. Include Content 1.1. Include 2. Include Header 2.1. Include 3. Include Footer 3.1. Include 图 3- 26 组合视图的时序图 利用 MVC 模式来构建表示层的应用,上面我们给出了有关控制器和视图模块构建 的一些模式,当然这并不是构建应用的唯一途径,在 MVC 模式下,我们还可以对不同的组 件进行模式化的设计和开发,象在构建 RequestDispatcher 和 Helper 这些组件时,我们还可 以考虑设计和优化出不同的设计模式,但整个设计的核心思想就是将我们的应用构建的更具 有可扩展性,便于维护,以及具有良好的结构,同时能更加方便的满足用户的实际需要。 小结 在本节中,首先我们对构建 J2EE 表示层的应用所需的技术进行了介绍,包括 JSP, Servlet 和新的 Web Service 技术,结合 WebLogic 讨论了如何构建个性化的应用,最后给出 了构建应用的一些设计模式。 第4章 EJB 构建业务逻辑层 EJB -- Enterprise Java Bean, 是 SUN 在服务器平台上推出的 JAVA 一门新 技术。与其他 J2EE 的技术一起, 大大增强了 JAVA 的能力, 并推动了 JAVA 应用 于企业级应用系统。 76 EJB 是商业逻辑层的组件技术, 与 JAVA BEANS 不同, 他提供了事务处理的 能力。 自从三层结构提出, 中间层也就是商业逻辑层, 是处理事务的核心, 由 于从数据存储层分离, 它就取代了存储过程的大部分地位。 但是,如何才能构建一个可靠而又高性能的 EJB 系统呢?光会写 EJB 的程序是不够的。 EJB 是一门复杂的技术,如果应用不当的话,你会构建一个出乎你想象中糟糕的系统。这一 章将会对构建 EJB 系统进行详细的讨论,但是这一章并不是 EJB 的入门教材,要求读者要 有 EJB 的基础知识。 4.1 EJB 的体系结构 软组件模型的思想是创建可重用的组件并将其组合到容器中,以得到新的应用系统。组 件模型定义了组件的基本体系结构、组件接口结构、与其他组件及容器相互作用的机制等。 利用组件模型规范说明,组件开发人员可以实现了应用系统逻辑组件,而应用系统开发人员 则把这些预先开发好的组件组合成应用系统,而应用系统也可以作为新的组件。软组件模型 思想已经在软件开发界迅速流行,因为它可以达到以下这些目的:重用、高层开发、通过工 具进行自动化开发,简化开发过程等。JavaBeans、EJB、COM/DCOM 等都是软组件模型的 例子。 有两种类型的软组件模型:客户端组件模型和服务器端组件模型。客户端组 件模型如 JavaBeans 是专门用于处理程序的表示及用户界面问题的;服务器端组 件模型如 EJB 则向面向事务处理的中间件提供基础设施。服务器端组件模型把组 件模型的开发和中间件联系在一起。企业级应用以其复杂性著称,它不仅涉及到 应用逻辑、并发性和伸缩性问题,而且涉及到如何把不兼容的系统组合在一起的 问题。服务器端组件模型解决了中间件开发的复杂性问题,它使中间件开发人员 集中于应用系统的逻辑部分,而无需关心处理同步、可伸缩性、事务集成、网络、 分布式对象框架等一些分布式应用系统中存在的复杂的细节问题。 下面,让我们深入的看一下 EJB 的体系架构。 4.1.1 N 层网络结构 在三层(多层)结构出现之前,大多数网站都使用 CGI 技术. CGI 实现了整 个系统的所有复杂的业务逻辑,没有考虑所消耗的系统资源。所以十几年后,随 77 着并发访问量的迅速增长,这些网站已经不堪重负。另外,由于业务逻辑没有清 晰的划分,原有的系统模块可重用性几乎为零,造成了系统升级与重新开发之间 划上了等号。所以,这种开发模式不适合有大量并发用户的系统。 因此,一种新的体系结构慢慢发展出来,把业务逻辑从网络服务器(web server)分离成几个独立的组件。这些独立的组件可以在不同的机器上以提高性 能,可以被浏览器,小应用(Applets),或是现在的轻量级的 CGI 访问,同时, 这些组件经过优化,大大提高了其性能,稳定性和容错性。 图 4-1 N 层网络结构 可以看到图 4-1 中,整个系统被分成四个部分: ·网络服务器(Web Server) ·应用服务器(Application Server) 78 ·事务监控器(Transaction Server) ·数据库服务器(Database Server) 为什么要把系统分成这么多块呢?把系统按功能划分成块,可以使每一块专 注于它自己的功能。另外,服务器的开发者可以针对该服务器的功能,对软件进 行尽可能的优化。例如,应用服务器是唯一和数据库交互的媒介,所以它可以在 启动的时候,预先和数据库建立多条连接形成共享数据库连接池,节省了在客户 端请求时才建立连接的时间。这个简单的措施在系统长时间运行时会大大提高系 统性能。 根据这些模块,我们又可以将我们的应用分为表示层、业务逻辑层、数据访 问层。在 J2EE 的应用中,表示层一般由 JSP,Servlet 来实现,提供整个系统与 用户交互的界面,这一层主要作用是对用户的传入参数作合法性验证,然后把参 数传给后端的相关服务(业务逻辑层),再接受返回的结果(如果有的话),展 示给用户看。业务逻辑层一般由普通的Java 类或会话(Session) Bean来实现, 它的作用正如其名,用来做业务逻辑,一般是对数据的处理,对文件的读写等等。 数据访问层一般由普通的 Java 类或实体(Entity) Bean 来实现,提供对数据 库的操作。 79 图 4-2 表示层,业务逻辑层,数据访问层 这里要指出的是,业务逻辑层和数据访问层并不是一定要用 EJB 来实现,有 些 J2EE 的初学者可能产生误会:如果不用 EJB 就不叫三层。其实这三层的划分 是按功能的,而不是按所用的技术。用 EJB 和一般的 Java 类都有各自的好处与 坏处。后面会针对它们的利弊作详细的比较。 4.1.2 关于组件的讨论 关于组件,1996 的面向组件编程欧洲工作组(European Workshop on Component-Oriented Programming,简称 ECOOP)给出了如下定义: A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software component can be deployed independently and is subject to composition by third parties。(译文:软组件是一种构成单元,规定了接口和外在 的上下文依赖性。软组件可以独立部署,并由第三方进行组装。) 组件可由多种语言开发,如 Java,C++,Visual Basic 等等。一个好的组件必须具有下列特 性: ·属性(properties) ·操作(operations) 80 ·事件(events) ·可重用(reusable) ·可共享(shareable) ·可分布(distributable) ·到处可发布,和服务器无关,和平台无关(ubiquitously deployable) ·自包含(self-containment) ·自描述(self-description) 其中,很重要的一个特性是自包含。这种特性不需要开发者来实现,而由组件服务器来 完成的。组件服务器会自动给组件添加一些基础服务(infrastructure services),这些服务不 需要开发者来书写,但又是组件所必需的服务。基础服务是整个企业系统都要用到的服务, 包括:事务服务、目录服务、安全管理、并发访问管理(多线程)、存储管理、资源优化、 系统管理、负载均衡、容错等等。提供这样一个架构允许开发者只需要在他们的组件里实现 业务逻辑代码,而不需要把宝贵的时间花费在对复杂的组件体系结构的了解上。另外,仅包 含业务逻辑的源代码比实现基础服务的源代码要清晰易懂。毕竟,要开发网上商城的购物篮 的人员去了解如何实现两阶段提交是不合理的。一个好的体系结构必须在组件和它的执行环 境之间定义严格的接口,这样组件服务器才能自动添加基础服务。 对 EJB 来说,开发者在这些 EJB 的代码中实现分布式应用的业务逻辑,为 EJB 书写部 署参数(deployment parameter),再把 EJB 打包到一个以 jar 为后缀名的文件里,到此开发 工作就完成了。但是,这个 EJB 的 jar 文件是不能直接用的,在这个 EJB 的发布过程中, WebLogic Server 会调用 weblogic.ejbc20 这个类对这个 EJB 重新编译,添加基础服务的代码。 经过编译后的 EJB 才能在 WebLogic Server 应用中被客户端调用。有兴趣的读者可以手工调 用 weblogic.ejbc20 来编译 EJB 的 jar 文件,加上-keepgenerated 参数保留 WebLogic 添加的代 码,供参考。如果 EJB 是按 EJB1.1 开发的,则用 weblogic.ejbc 这个类来编译。 既然组件在实现时只有业务逻辑的代码,那么加入的基础服务由谁来调用呢?在一个组 件集成的系统中,容器(Container)在客户端和服务器的交互中起着重要作用。 图 4-3 容器 如图 4-3,我们可以看到当一个客户端调用组件的一个方法来做业务处理时,容器会截 获这个请求,在调用组件的方法之前,它先会调用基础服务的方法:开始事务,安全检验, 从数据库中提出数据等等;然后它才会去调用客户端要调用的方法;最后,在向客户端返回 结果之前,它同样会调用基础服务的方法:根据方法执行的情况提交或回滚事务,把数据写 回数据库等等。 81 这样的体系结构本身实现了复杂的基础服务,以及这些服务的集成,而开发者只需注重 对其系统业务逻辑的分析建模,大大减少开发的时间和工作量。 4.1.3 EJB 的分类 EJB n (Enterprise JavaBea) 是以组件为基础的一门技术。它的出现,使得开发者可以快 速而又成功的开发出基于组件的分布式应用。EJB 是服务器端组件的标准,而这个标准是由 SUN 公司的企业 JavaBean 规范(Sun Microsystem's Enterprise JavaBeans specification )定 义 的。WebLogic Server 按照 EJB 规范实现了 EJB 的体系结构。 我们来看一下 WebLogic Server 的实现。 图 4-4 EJB 的应用架构 从图 4-4 可以看出,客户端与 EJB 服务器之间的通讯可以通过 Java RMI,CORBA IIOP ,甚至是 Microsoft DCOM。EJB 容器来完成这些协议的转换、 数据的编码等等。客户端通过 EJB 来访问整个企业的应用,EJB 本身也可以访问 一些遗留下来的老系统(如 mainframe)、3GL 的应用(COBOL,PL/1)、数据库 (Oracle,Sybase,DB2)以及企业中其他系统(SAP,PeopleSoft,Baan)。所有的 这些与外部资源的通讯都是通过系统的容器来完成。容器可以通过配置来完成多 82 种服务,但这些服务取决于应用服务器的用途是什么。这些不同的服务都遵循下 列规则: ·应用服务器提供基础服务的实现,如安全,存储,事务等等。 ·应用服务器其中可以包含一个或多个容器,这些容器可以是应用服务器产 生的,或是第三方的。 ·容器提供了 WebLogic Server 对 EJB 规范的实现。 ·EJB 实例在容器内部存在,并且只能被一个容器管理。 ·容器与 EJB 之间的接口是按照 EJB 规范的,但容器与 WebLogic Server 之间的接口是 WebLogic Server 开发小组规定的。 ·EJB 对象在容器内部实例化。 ·一个容器中可以有多种 EJB。 EJB 2.0 规范 定义的下列 4 种 EJB: ·无状态会话 Bean(Stateless Session) ·有状态会话 Bean(Stateful Session) ·信息驱动 Bean(Message-driven) ·实体 Bean(Entity) 会话 EJB 的一个特点是不会永远存在,一旦服务器关掉了或崩溃了,它们的 数据就丢失了。所以它们是生存时间相对短,非持久性的 EJB。从客户端的角度 来看,会话 EJB 是一个实现一些业务功能的对象,客户端可以自由的操作这些 对象来完成它的工作。 83 无状态会话 EJB 是实现了单一使用的服务的组件。这种服务可以多次调用, 但是无状态会话 EJB 在方法调用之间不会保持与客户端相关的数据。当它的方法 被调用时,这个方法必须完成它的业务逻辑而又不能对该 EJB 的属性进行修改。 当然,开发者是可以为无状态会话 EJB 赋几个属性,并在方法中修改它的属性, 这是完全可行的。但是,在 EJB 服务器中对无状态会话 EJB 的实现不会保留这 些修改,所以在方法调用结束后,客户端对服务器端数据的更改就无效。从这一 点来说,无状态会话 EJB 相当于一个没有属性的 Java 对象。这种调用只能提供 单一使用。在许多方面,无状态会话 EJB 提供了可重用的单次使用的服务。如果 客户端要调用无状态会话 EJB 并要保留两者交互的状态,则必须在客户端保留。 无状态会话 Bean 有下列特点: ·提供代表业务操作的单次使用的服务 ·不会维持客户端的状态 ·一个实例可以被多个客户端调用 ·EJB 服务器关掉了或崩溃了之后不会存活 ·生存时间相对短 ·相同的无状态会话 EJB 的任意两个实例都是相等的 适合于用无状态会话 EJB 的例子有:计算 cos(x)的 EJB,用 zip 格式压缩 100 字节的 EJB,检查一个股票代码是否合法的 EJB,根据地名返回邮编的 EJB。 有状态会话 Bean 和无状态会话 Bean 很相似。实际上,同一个 EJB 可以发布 成有状态会话 Bean ,也可以发布成无状态会话 Bean。那么,它们的区别在哪里 呢?有状态会话 Bean 是被设计成可以在方法调用之间维护客户端的状态,就像 HTTP Session 一样。有状态会话 Bean 会把这些状态存在它的属性中。EJB 容器 会保证同一个客户端的每次调用都会被转到这个保持它的状态的有状态会话 84 Bean 的实例;而由于无状态会话 Bean 不需要保持客户端的状态,所以 EJB 容器 不能保证同一个客户端的两次调用都被转到同一个实例。但是,有状态会话 Bean 要维持状态而且每个客户端都要有自己的实例,因此,并发客户数一大,内存消 耗的就很大。为此,EJB g规范规定 EJB 容器可以暂时把不正被使用的有状态会 话 Bean 的实例写到磁盘上,这个过程叫钝化(passivation),等这个实例被调 用了在把它从磁盘上读出来,这个过程叫活化(activation)。这样,EJB 容器 可以有效的使用内存。无状态会话 Bean 没有钝化和活化的过程。 有状态会话 Bean 有下列特点 ·提供与客户端的对话交互 ·维持客户端的状态 ·一个实例只能被一个固定的客户端调用 ·EJB 服务器关掉了或崩溃了之后不会存活 ·生存时间相对短 适合有状态会话 Bean 的例子有:用作网上商城中的购物篮的 EJB,管理呼 叫中心的工作流的 EJB,在旅行网站上预定机票和旅馆的 EJB,在游戏中记录玩 者得分的 EJB。 消息驱动 Bean 是 EJB 2.0 规范新引入的组件。它很像无状态会话 Bean,但 是它是异步的。所谓同步的组件是实现了阻塞和等待的行为。例如,当客户端调 用无状态会话 Bean 的一个方法时,客户端的程序会阻塞住,直到 Bean 的方法完 成才会继续进行下去。在异步模式里,客户端调用 Bean 但不等待 Bean 的返回, 而直接向下进行。 消息驱动 Bean 与 Java 消息服务(Java Message Service)紧密结合,它的 许多概念都来自 JMS 规范。JMS 规范定义一系列用来构成面向消息的中间件系 85 统。JMS 客户端向在应用服务器里的 JMS 目的地(destination)发送消息,这 是一个轻量级的操作,只需消耗很少的资源。在消息发送之后,它不会知道这个 消息是否到达目的地,也不会关心消息的接受。JMS 服务器会处理消息的接收, 并把消息转发给消息的消费者。消息驱动 Bean 被设计成一种特殊的 EJB,可以 接收从 JMS 客户端发送的消息。消息驱动 Bean 没有 Home 接口和 Remote 接口, 这是和其它的 EJB 不同的。WebLogic Server 直接与消息驱动 Bean 交互,创建 Bean 的实例,并把消息传给这些实例。客户端不能直接调用消息驱动 Bean,只 能通过发消息来触发。 图 4-5 Message-driven Bean 消息驱动 Bean 有下列特点: ·是异步的无状态的组件。 ·它的行为和无状态会话 Bean 很相似。 ·通过 JMS 消息来调用。 86 适合消息驱动 Bean 的例子:当一个消息出现时发送 E-Mail 的 EJB,一个进 行长时间计算的 EJB,把信息异步写到日志中的 EJB,把一个 JMS 目的地中的消 息发送到另一个 JMS 目的地中的 EJB,总之,适合于任何一个可以在后台运行、 结果不需要立刻知道的操作。 实体 Bean 的一个特点,也是它和以上几种 EJB 的不同之处是实体 Bean 是 可持久(persistent)的EJB。当我们说一个EJB 是可持久的,是指不论这个EJB 是否在内存中该 EJB 的数据都存在。一个 EJB 的持久性可以有多种实现,通常是 存放在关系数据库中,也可以放在文件中或是别的什么介质中。 当一个实体 Bean 的实例被创建时,这个实例的数据同时被存储到持久性的 存储介质上(比如通过数据库的插入(insert)操作),这些数据在内存中也有 一份拷贝,被该实例管理。只要内存中的数据被修改,对应的在存储介质上的数 据也会自动更新。因为 EJB 的数据是存放在存储介质上的,所以多个客户端可以 同时访问相同的数据。容器对多个客户端请求相同的数据有多种实现方式。例如, 容器只在内存中保留一份拷贝,并序列化客户端的请求(在任一给定的时刻只能 有一个客户端在使用);或者它生成多份拷贝供客户端使用(这时容器必须协调 对数据的并发更新)。多个客户端使用相同的实体 Bean 实例和多个客户端使用 相同会话 Bean 实例是不同的。实际上,多个客户端使用相同的实体 Bean 实例 意味着它们访问了在存储介质上的相同数据。容器可以创建一个或多个实例来管 理多个客户端如何共享数据。这些概念已经涉及到 WebLogic Server的实现方法, 我们将在后面对实体 Bean 的深入讨论中分析。 实体 Bean 的生命周期不仅仅局限于服务器的生存时间。服务器的结束只是 内存中的数据没有了,但是在存储介质上的数据仍然保留。 实体 Bean 有下列特点: ·它们代表了存储介质上的数据。 ·它们可以在服务器关掉了或是崩溃了之后存在。 87 ·多个客户端可以使用代表相同数据的 EJB。 ·实体 EJB 管理着存储介质上的数据在内存中的拷贝。 ·代表的系统中的业务数据。 适合于实体 Bean 的例子:代表了一个足球运动员职业数据的 EJB,代表一 支股票历史价格的 EJB,代表个人档案的 EJB,代表一个养牛场每个月产肉量的 EJB。 从系统设计上的角度来说,实体 Bean 尽量不要包含系统的业务逻辑,它仅 仅代表了存储介质上的数据。业务逻辑应该用会话 Bean 来实现,会话 Bean 根 据需要来操作实体 Bean,从而修改存储介质上的数据。但这也不是绝对的,有 时出于性能上的考虑,也会让实体 Bean 完成一些简单业务逻辑。 4.1.4 客户端对 EJB 的调用 在提及客户端对 EJB 的调用之前,必须要简单的提一下 Java RMI(Remote Method Invoke,远程方法调用)。客户端通过 RMI 可以调用服务器端对象的方 法。每个可以被客户端调用的远程对象(Remote Object)都必须有根(Stub) 和骨架(Skeleton)。根和 Skeleton 在分布式系统中用来进行网络通讯,数据 编码及对Remote Object的方法调用。根和Skeleton可以自动的从Remote Object 产生。WebLogic 使用 weblogic.rmic 这个类来生成这两个对象。 根(Stub)是 Remote Object 的轻量级版本,它有和 Remote Object 一样的 接口(interface),并且驻留在客户端的机器上。因为根有和 Remote Object 一样的接口,客户端可以像使用 Remote Object一样使用根的方法。根会把客户 端对方法的调用转换成可以在网络中传播的网络消息,发送到服务器。 骨架(Skeleton)是一个驻留在服务器端的很小的对象,它可以把客户端传 来的网络消息转换成对服务器端对象的方法调用。在方法结束后,Skeleton 会 88 得到方法的返回值,再把返回值转换成网络消息,发送到客户端。这时,根会把 网络消息转换成可以使用的 Java 对象,供客户端使用。 图 4-6 RMI EJB 由两个接口给客户端使用: ·Home interface ·Remote interface 因此,每个 EJB 由两个根和两个 Skeleton,这是在发布时,weblogic.ejbc20 生成的。 89 远程接口(Remote interface)包含了这个 EJB 的业务操作;Home interface 是 EJB 提供的一些控制它的生命周期的方法。这些方法有:创建新的实例,删除 实例,提供该 EJB 的信息等等。Home interface 不会包含任何业务逻辑。不同 的 EJB 有且仅有一个它自己的 Home interface。在 WebLogic Server 启动时, 它会把所有已发布的 EJB(除了消息驱动 Bean)的 Home interface 根对象绑到 JNDI 树上,给客户端下载。每个客户端都会得到一份 Home interface 根的拷 贝。 图 4-8 客户端对 EJB 的调用 图 4-8 显示了客户端对 EJB 的调用过程。我们来详细看一下: 1) 客户端(JSP/Servlet,或是远程的 Java 应用程序)到 服务器的 JNDI 树上查找 Home 根。 2) 客户端下载 Home 根。 90 3) 客户端得到 Home 根后,调用 create()或 find()来创建 EJB 实例。这些调用将使根与容器中的 Home Skeleton 进行 RMI 通 讯 4) Home Skeleton 接收到根的网络消息后,会作相应的操 作,创建 EJB 实例和 Remote 根,Remote Skeleton。 5) Remote 根被返回给客户端。 6) 客户端拿到 Remote 根之后就可以进行业务操作。 对客户端来说,有时需要判断调用的两个 EJB 实例是否时同一个实例。这是 和 EJB 的类型相关的。对无状态会话 Bean 来说同一个 EJB 的任何两个实例都是 相等的,对消息驱动 Bean 来说,客户端不可能调用到它的实例,所以需要讨论 的是有状态会话 Bean 和实体 Bean。 两个有状态会话 Bean 的实例只有在它们有同一个 client context(客户端 上下文)时才能认为这两个实例实际上是同一个实例。注意,如果两个有状态会 话 Bean 的实例仅仅是它们的状态相等,则它们不一定是同一个实例。应用服务 器很难对两个对象的属性进行细致的比较。那么应用服务器如何判断两个客户端 是否调用同一个 EJB 的实例呢?如果这两个客户端有相同的客户上下文就意味 着它们是用同一个 EJB 实例,因为一个有状态会话 Bean 实例只能有一个客户上 下文。 91 图 4-9 两个客户端共用一个客户上下文(client context) 两个客户端怎样才能有相同的客户上下文呢?如果这两个客户端使用相同 的 Remote 根和 Remote Skeleton,则它们就有相同的客户上下文。这种情况只 有第一个客户端把它和 EJB 的连接传了一份拷贝给第二个客户端时才可能。两个 独立的客户端向服务器请求和一个有状态会话 Bean 建立连接时,只会产生两个 不同的客户上下文。 图 4-10 如何传递客户上下文 可以看到客户端传递客户上下文有四个步骤: 1) 客户端创建一个新的 EJB 实例。 2) 客户端把该实例的句柄(Handle)存在一个全局的存储区里。 句柄是用来保存对 EJB 实例引用的对象。同一个句柄对象总是引用同一 个 EJB 实例。 3) 第二个客户端从全局的存储区里得到句柄对象。 4) 第二个客户端用这个句柄创建同一个远程引用。 判断两个实体 Bean 实例是否是同一个实例要简单一些。每个实体 Bean 都 有它的关键字(Primary Key,简称 PK) 类。这个 PK 类对应着实体 Bean 所代 92 表的数据库中表的关键字。只要这两个实例的 PK 相等,这两个实例实际上就是 同一个实例。 图 4-11 判断实体 Bean 实例是否相等 4.2 WebLogic Sever 的 EJB 容器 这一小节里我们将讨论 WebLogic Server 的 EJB 容器的行为。容器为其中 的 EJB 提供生命周期控制、性能优化、事务控制、容错等服务,我们必须了解这 些服务,这对开发和系统设计都是很重要的。 2.1 WebLogic Server 中 EJB 的生命周期 我们将在这里从服务器的角度来分别讨论四种 EJB 在 WebLogic Server 容 器中的生命周期。首先是无状态会话 Bean。 2.1.1 无状态会话 Bean 的生命周期 WebLogic Server 用一个游离池(free pool)来提高无状态会话 Bean 的性能。这个游离池是专门存放空闲(unbound)的无状态会话 Bean 实例的。所 谓空闲是指这个 EJB 的实例没有处理客户端的请求。 下面的这幅图描述了 WebLogic Server 的游离池,及无状态会话 Bean 进入游离池和离开游离池的处理。虚线中是 EJB 实例的状态。 93 图 4-12 无状态会话 Bean 的生命周期 默认的,WebLogic Server 在启动时,它的内部不会有 EJB 的实例。当客户 端访问某个无状态会话 Bean 的时候,WebLogic Server 会初始化一个新的实例 来处理客户端的请求。 但是,你可以设置 weblogic-ejb-jar.xml 的 initial-beans-in-free-pool 属性,使 WebLogic Server在启动时自动在游离池创建空闲的 EJB 实例。这样在 访问 EJB 时可以提高初始化的速度,因为当客户端访问 EJB 时,WebLogic Server 会先到游离池中寻找是否有空闲的 EJB 实例,如果有,就把它从游离池中取出来 处理请求,如果没有,容器才会初始化新的实例。Initial-beans-in-free-pool 的默认值是 0。你也可以设置游离池中可存放的 EJB 实例的最大个数 max-beans-in-free-pool,理论上这个值可以达到 int 的最大值,但是实际要看 内存有多大。 当客户端调用一个无状态会话 Bean 的方法时,WebLogic Server 从游离池 中取出一个实例。这个实例在方法的执行过程中处于活跃状态,当方法完成后, 这个实例又返回到游离池中去了。所以,一个客户端如果调用同一个无状态会话 Bean 的两个方法,可能是两个不同的实例分别处理了一次调用。只是因为 WebLogic Server 会到游离池中取两次实例,在第二次时,可能会取到上一个实 94 例,也可能上一实例这时正被别的客户端使用,不在游离池中,所以 WebLogic Server 取了另一个空闲的实例。 如果所有的实例都在处理请求,而实例的总数又已经到达了 max-beans-in-free-pool 的数,那么新的客户端会在请求时阻塞,直到有一个 实例完成了方法调用。如果阻塞时间超过了一个事务超时时间(Transaction Time out),或这个方法调用没有用到事务,但是过了五分钟,WebLogic Server 会抛出 RemoteException(异常)。 通常,你不必设置 max-beans-in-free-pool。一般,在游离池中的实例数 可能有三种情况: ·有一个实例在游离池中,你可以用这个实例来处理请求。 ·游离池中没有可用的实例,但 max-beans-in-pool 没有到,WebLogic Server 会初始化新的实例。 ·游离池中没有可用的实例,且 max-beans-in-pool 到了。只有等待有一个 实例完成请求,或是超时。 设置 max-beans-in-free-pool 的唯一理由是限制资源的使用。 如果把 max-beans-in-free-pool 设成 0,会怎样: ·实体 Bean 总是初始化新的实例。 ·无状态会话 Bean 总是初始化新的实例。 ·有状态会话 Bean 不适合。这些实例是不会和池有关系的。 ·消息驱动 Bean 非法值。WebLogic Server 在运行时不会初始化实例,所 以这个值必须大于 0. 95 2.1.2 消息驱动 Bean 的生存周期 WebLogic Server 对消息驱动 Bean 的生存周期的控制和无状态会话 Bean 几 乎一样。WebLogic Server 也使用游离池来提高消息驱动 Bean 的性能。 但 WebLogic Server 在消息驱动 Bean 所监听的 JMS 目的地中有新消息出现 时初始化新实例,和无状态会话 Bean 不同。这是因为消息驱动 Bean 是消息触发 的。 2.1.3 有状态会话 Bean 的生存周期 WebLogic Server 用缓存(cache)机制来提高有状态会话 Bean 的性能。缓 存里保存了在内存中活跃的有状态会话 Bean 的实例,以便它们可以立刻响应客 户端请求。所谓活跃的有状态会话 Bean 的实例是指内存中正在被客户端使用的 实例和刚刚被客户端使用过的实例。缓存和游离池不一样。对客户端来说,游离 池中的任何一个实例都是可以用的,而在缓存中,只有存放了它的数据的那个特 定的实例才是可以用的。 下面这幅图描述了 WebLogic Server 的缓存,以及有状态会话 Bean 的实例 进入和离开缓存的过程。 96 图 4-13 有状态会话 Bean 的生存周期 在 WebLogic Server 启动时,它的里面不会有有状态会话 Bean 的实例。当 客户端查找和获得它自己的有状态会话 Bean 的引用时,WebLogic Server 初始 化新的实例,并把它存放在缓存中。 因为要为每个客户端都保留它特定的实例,所以有状态会话 Bean 对内存的 消耗较大,为了得到好的性能,WebLogic Server 会在缓存中只保留正被使用的 和刚刚被使用的实例,而不满足这个条件的实例(如很久没被客户端调用)会被 钝化(deactivate)。WebLogic Server 会把它们移出缓存,并把它们的状态写 在磁盘上。当然,这些状态必须是可序列化的。 WebLogic Server 提供 max-beans-in-cache 这个在 weblogic-ejb-jar.xml 的元素,用来对 EJB 实例的钝化作一些控制。 如果 max-beans-in-cache 到了,WebLogic Server 会把缓存中不处于正被 使用的实例钝化一些,即使这些实例没有到达它们的空闲超时 (idle-timeout-seconds,后面会讨论)。如果 max-beans-in-cache 到了,缓 存中所有实例都正在被使用,WebLogic Server 会抛出 CacheFullException 异 常。 注意,当一个 EJB 实例满足了钝化的条件,并不意味着 WebLogic 会立刻把 它写到磁盘上去。实际上,这个实例可能根本没有被钝化。钝化只发生在服务器 资源不足时,或是 WebLogic Server 对缓存作固定的维护时。 Max-beans-in-cache 和 idle-timeout-seconds 元素也对有状态会话 Bean 从缓存中或从磁盘上删除作了一些控制。 对于在缓存中的实例,当资源紧张和缓存需要内存时,WebLogic Server 会 检查缓存中有哪些有状态会话 Bean 的实例数到达了 max-beans-in-cache。如果 97 这些 Bean 的实例中没有被客户端调用的时间超过了它们的 idle-timeout-seconds,这些实例会被直接删除,而不是被钝化,从而释放资源。 如果一个实例的 idle-timeout-seconds 到了,即使这种有状态会话 Bean 的 max-beans-in-cache 数还没到,它也会被删除。 如果把 idle-timeout-seconds 设成 0,WebLogic Server 会停止删除实例。 当缓存资源紧张时,WebLogic Server 只会钝化实例。 对已经钝化的实例,如果客户端没有在 idle-timeout-seconds 到达之前调 用它,WebLogic Server 会把它从磁盘上删除。 WebLogic Server 会在钝化时试图序列化所有没有被声明为临时 (transient)的字段。EJB 开发者必须保证所有的非临时字段都可以序列化, 就像 Remote 或 Home 接口。根据 EJB 1.1 规范,一个 EJB 的非临时的字段也包 括: ·对 EJB 的 JNDI 环境上下文的引用 ·对 UserTransaction 的引用 同样,根据 EJB 1.1 规范,javax.ejb.Session 不能声明为临时。 2.1.4 实体 Bean 的生命周期 实体 Bean 的生命周期要相对复杂一些。WebLogic Server 对实体 Bean 也 用池技术来提高实体 Bean 的性能,但是这种池和无状态会话 Bean 的游离池不 同,我们来具体看一下图 4-14。 一个实体 Bean 在它的生命周期里可以有三种状态: ·不存在(does not exist) 98 ·游离态(pooled) ·就绪态(ready) 在游离态的 EJB 实例可以被认为裸(bare naked)实体对象。这些对象是被 创建的,并且 WebLogic Server把上下文 Context 赋给它们了,但是它们没有标 识符(如关键字 Primary Key)。它们的所有与数据库表对应的字段都没有被实 例化。因为在游离态的 EJB 实例没有和关键字联系起来,WebLogic Server 会认 为所有在游离态的实例都是一样的。实际上,WebLogic Server 对游离态的实体 Bean 实例的处理和无状态会话 Bean 是一样的。 图 4-14 实体 Bean 的生命周期 当客户端调用 create(),find()或是别的在 Home interface 的方法, WebLogic Server会从池中取出一个实例来执行客户端的请求。执行非 create() 的 Home interface 中的方法时,WebLogic 并不会给这个实例一个关键字,而且 这个实例仍然处在游离状态,它会返回一个或多个关键字,但是它本身不会作为 99 代表某个关键字对象返回。之后,WebLogic Server 会从池中选出一些实例,把 方法返回的关键字分别赋给它们,这时,原先执行 Home interface 中方法的实 例可能会被 WebLogic Server 选中,从而得到关键字。而客户端调用 create() 方法时,处理这个方法的实例会直接和客户端传入的关键字联系起来。 当 EJB 实例有一个关键字(Primary Key)时,WebLogic Server 会把它从 游离状态移到就绪状态。这个过程叫活化(Activation)。注意,这和会话 Bean 的活化是不同的。会话 Bean 的活化是把 EJB 实例从磁盘上读到内存中。实体 Bean 的钝化(Passivation)是指 WebLogic Server把 EJB 实例的关键字(Primary Key)清除,使它重新成为裸实体的过程。实体 Bean 的活化和钝化不会涉及到 磁盘存储。 虽然实体 Bean 的实例有了一个关键字,处于就绪状态,但它的其它字段可 能还没有从数据库中读出来。这点是很重要的。为了性能优化,先进的 BMP 和 CMP 实现了即时读取的机制。WebLogic Server 只有在必须和数据库同步数据时 才会调用 ejbLoad()。 总结一下实体 Bean 的游离状态和就绪状态转换有下列几种情况: 1) 游离态到就绪态 ·客户端调用 create()。 ·WebLogic Server 活化一个实体 Bean 的实例。 2) 就绪态到游离态 ·客户端调用 remove()。 ·WebLogic Server 钝化一个实体 Bean 的实例,它会按 LRU 算法来 挑选。 100 当 WebLogic Server需要更多的裸实体来服务 create(),find()等请求 时,会初始化一些实例把它们放在池中;当然如果池中的实例太多了, WebLogic Server 会把一些多余的实例转成“不存在”(does not exist) 状态。 图 4-15 Entity Bean Creation 的过程 101 图 4-16 实体 Bean 装载的过程 图 4-17 实体 Bean 删除 & 消亡的过程 4.2.1 实体 Bean 的 ejbLoad()和 ejbStore() WebLogic Server 用 ejbLoad()和 ejbStore()来读写实体 Bean 的持久性域 (persistent fields)。所谓持久性域是实体 Bean 用来对应数据库表中某些 列的字段。默认的,WebLogic Server会按下列方式调用 ejbLoad()和 ejbStore(): 1) 一个事务为实体 Bean 初始化好了。客户端可以显式初始化 一个新的事务然后调用这个 Bean,或者客户端没有初始化事务,由 WebLogic Server 根据 Bean 的部署描述(Deployment Descriptor) 中方法的事务属性来初始化一个新事务。 2) WebLogic Server 调用 ejbLoad()来从数据库中获得 Bean 的 最新的数据。 102 3) 在事务提交时,WebLogic Server 调用 ejbStore()把 Bean 的持久性域写回到数据库中。 调用 ejbLoad()和 ejbStore()的简单步骤,可以保证新的事务总是用到实体 Bean 最新的数据,而且总是在事务提交时把数据写回到数据库中。在某些条件 下,通常是性能的原因,唉,你可能想要限制 ejbLoad()和 ejbStore()的次数。 相对的,你也可能希望 ejbStore()更频繁一些,这样就可以使别的应用在事务 提交之前看到数据的中间状态。 WebLogic Server提供几个发布参数来控制 ejbLoad()和 ejbStore()的调用。 4.2.1.1 用 db-is-shared 来限制对 ejbLoad()的调用 WebLogic Server 的默认行为是在每个事务开始的时候调用 ejbLoad(),因 为一般的系统都是有多种应用会修改数据库。当多个客户端(包括 WebLogic Server 自己)都要修改实体 Bean 对应的底层数据库的数据时,调用 ejbLoad() 可以使 Bean 在内存中的数据和数据库中的数据一致,这样才能保证使用的是最 新的数据。 在某些特殊的环境下,只有一个 WebLogic Server 来访问某个实体 Bean, 调用 ejbLoad()是没有必要的。因为没有别的客户端或系统会更改底层数据库中 的数据,这个 Bean 保存在内存中的数据总是与数据库中的数据一致的。这时, 再调用 ejbLoad()只是浪费系统资源。为了避免在这种情况下多余的调用 ejbLoad(),WebLogic Server提供了 weblogic-ejb-jar.xml 中的 db-is-shared 参数。这个参数的默认值被设成 true(真),你必须得把它改成 false(假)。 当 db-is-shared 被设成 false 时,WebLogic Server 只会在下列两种情况下调 用 ejbLoad(): ·客户端第一次引用这个 Bean 时。 ·EJB 的事务回滚时。 103 对 db-is-shared 的限制和警告:如果你错误地在多客户端的情况下把 db-is-shared 设成 false,那么数据库的数据被更改了,WebLogic Server 也不 会调用 ejbLoad(),数据的完整性就会被破坏。另外,因为 WebLogic Server Cluster(集群)要用到池技术,所以不能在 WebLogic Server 集群环境中把 db-is-shared 设成 false。 4.2.1.2 用 is-modified-method-name 来限制对 ejbStore()调用 注意:这个方法只用于EJB 1.1 CMP(容器管理的持久性),WebLogic Server 6.0 的 EJB 2.0 CMP 的实现会自动监测容器管理的持久性域(CMP fields)的更 新,并且只把这些更新的字段写回数据库。我们建议你在 BMP 不要使用 is-modified-method-name,因为你既要实现 is-modified-method-name 方法, 又要实现 ejbStore()。 默认的,WebLogic Server在每个事务成功提交时会调用 ejbStore()把数据 写回数据库,即使这些数据实际上没有被更新。这种不必要的 ejbStore()的调 用会导致可怜的性能。因此,WebLogic Server 提供 is-modified-method-name 来控制对 ejbStore()的调用。 为了使用 is-modified-method-name,EJB 开发者必须写一个方法,这个方法 能在持久性域被更新时暗示 WebLogic Server有更新发生。这个方法在没有更新 发生时返回 false,在有更新发生时返回 true。 EJB 开发者在 weblogic-ejb-jar.xml 指定 is-modified-method-name 所对 应的方法。WebLogic Server 在事务提交时调用这个方法,只有在这个方法返回 true 时才调用 ejbStore()。 对 is-modified-method-name 的警告:is-modified-method-name 可以限制 不必要的 ejbStore()调用,从而提高性能,但是 EJB 的开发者需要能够正确的 判断更新发生的所有情况,如果 is-modified-method-name 方法返回一个错误的 标志,数据完整性的问题可能会发生,而且很难查出。如果你发现你的系统中的 104 实体 Bean 的更新“丢失”了,你必须检查所有的 is-modified-method-name 方 法,或者你可以用 WebLogic Server 默认的 ejbStore()的行为,可能可以纠正 这个问题。 4.2.1.3 用 delay-updates-until-end-of-tx 来改变 ejbStore()的行为 默认的,WebLogic Server 只会在一个事务成功提交时更新底层数据库的数 据。这可以避免不必要的更新以提高性能,防止重复更新。 如果你的数据库的隔离级别(isolation level)是 READ_UNCOMMITED,你 可能需要允许别的数据库用户可以察看数据在事务的中间状态。这种情况下, WebLogic Server 的默认行为就不适合了。 你可以把 delay-updates-until-end-of-tx 设成 false 来改变 WebLogic Server 的默认行为,WebLogic Server 会在每个方法结束后调用 ejbStore(), 而不是在整个事务成功提交时。 注意,把 delay-updates-until-end-of-tx 设成 false,不会使数据库在每 次方法调用后提交,这些更新仅仅是送到数据库而已,最后这些更新是否提交还 要看事务的结果。 4.2.2 把实体 Bean 设成 Read-Only(只读) 实体 Bean 也可以用只读(read-only)的并发策略来改变 ejbLoad()和 ejbStore()的行为。可以通过更改 weblogic-ejb-jar.xml 的 concurrency-strategy(并发策略项)来指明只读。 4.2.2.1 只读(Read-Only)并发策略 如果实体 Bean 永远不会被客户端更新,但是可能会被外部资源定期更新, 它可以使用只读并发策略。例如,一个只读的实体 Bean 可以代表某个公司的股 票,这个股票只会被 WebLogic Server 外部的系统更改。 105 WebLogic Server 永远不会调用只读的实体 Bean 的 ejbStore(),在 EJB 实 例被创建时会调用 ejbLoad(),然后 WebLogic Server 会每隔一段时间再调用 ejbLoad()。这个时间间隔是由read-timeout-seconds(只读超时间隔)指定的。 4.2.2.2 2.3.2 读写(Read-Write)缓存策略 读写(read-write)策略定义了 WebLogic Server对实体 Bean 的默认行为。 对读写的实体 Bean,WebLogic Server会在每个事务开始时调用 ejbLoad(), 或根据 db-is-shared;在每个事务成功提交时调用 ejbStore(),或根据 is-modified-method-name。 4.2.2.3 2.3.3 只读多态失效(Read-Only Multicase Invalidation) 只读多态失效(Read-Only Multicase Invalidation)适合于这种应用:数 据很少被更新,但是一旦被更新,原来的数据就会被告知失效,并且重新从数据 库中取出最新的数据。 你可以调用 CachingHome 或 CachingLocalHome 接口中的下列“失效方法“使 一个只读的实体 Bean 失效: package weblogic.ejb; public interface CachingHome{ public void invalidate(Object pk) throws RemoteException; public void invalidate(Collection pks) throws RemoteException; public void invalidateAll() throws RemoteException; } 106 当失效方法被调用时,本地服务器中的只读 实体 Bean 会失效,同时一条 广播消息会发送给同一个集群(cluster)中别的服务器,告知它们使它们的这 个只读实体 Bean 也失效。下一次对这个 Bean 的调用会导致 ejbLoad()的调用。 失效方法必须在事务完成后调用,如果它在事务的过程中调用,ejbLoad() 可能会读取事务之前的数据,在事务提交后,数据可能会和数据库不一致。 如果并发策略选择只读且设置了 read-timeout-seconds,当实体 Bean 被调 用时,WebLogic Server 会检查内存中的数据是否在 read-timeout-seconds 之 前从数据库中取出的,如果是,ejbLoad()会被调用,否则,内存中的数据会继 续被使用。WebLogic Server 为主读模式提供自动的失效方法。在这种模式中, 有一个读写 实体 Bean 和一个只读 实体 Bean,它们映射到同样的数据,可以 用只读 实体 Bean 来读数据,用读写 实体 Bean 写数据。详见 4.2.3.5。 4.2.3 只读 EJB 的限制 使用只读并发策略的 EJB 必须遵循下列限制: ·不能更新 EJB 的数据,因为 WebLogic Server 从来不调用 ejbStore()。 ·事务的属性必须设成 NotSupported。 ·EJB 的方法调用必须是等幂(idempotent)的。 ·因为数据库的数据可能被外部资源修改,所以用 read-timeout-seconds 控制 ejbLoad()。 4.2.4 主读(Read-Mostly) WebLogic Server 在 weblogic-ejb-jar.xml 并没有对主读的设置。但是如 果 EJB 很少被更新的话,可以用只读和读写的混合来实现主读。只读的实体 EJB 107 每隔 read-timeout-seconds 就去读取数据库的数据。有一个读写的实体 Bean 和只读的实体 Bean 对应数据库中同样的数据,并且会每隔一段时间更新数据。 当使用主读模式时,可以采用下列建议以避免数据一致性的问题: ·对只读的实体 Bean,如果它们对应的数据可能在一个事务中被修改,则 把它们的读超时时间参数 read-timeout-seconds 设成相同。 ·对所有的只读的实体 Bean,要把它们的读超时时间 read-timeout-seconds 设的尽可能小,但也不要严重影响性能。 ·保证读写的实体 Bean 更新的数据尽量小,避免在 ejbStore()中更新大量 的或是没有被被改变的字段。 ·保证读写的实体 Bean 更新数据的时间尽量小,避免事务的时间比它们的 只读的兄弟的 read-timeout-seconds 长。 4.3 WebLogic Server 集群中的 EJB 这里将讨论在 WebLogic Server集群中的 EJB 的行为及它们的事务,并且将 解释一些会影响集群中 EJB 行为的关键的发布参数。 在单一服务器的环境中,客户端通过 EJB Home 接口来查找EJB,而 Home 接 口在服务器端对应了一个 Home 对象;在引用了 EJB 后,客户端通过 Remote 接 口来调用 EJB 的业务方法,而 Remote 接口对应着服务器端的 EJB 对象。 108 图 4-18 在单服务器中的 EJB EJB 的容错只能发生在客户端和这个 EJB 之间。 4.3.1 在集群中的 EJB 对象 在 WebLogic Server 集群中,Home 对象在服务器端的表示被一个集群敏感 (cluster-aware)的根(stub)所取代。这个集群敏感根知道在集群中所有 WebLogic Server 上的 EJB Home 对象,它能把对 EJB 的查找请求发送到集群中 空闲的服务器上去,实现负载均衡,同时它也可以把请求在服务器崩溃后自动转 发到集群中别的服务器上去,实现自动容错。 无状态会话 Bean、有状态 Bean 话和实体 Bean 都可以有集群敏感的 home 根,这是由 weblogic-ejb-jar.xml 中的 home-is-clusterable(home 可集群) 属性指定的,如果这个属性被设成 true(默认值),WebLogic Server会生成集 群敏感的 home 根。 109 图 4-19 集群中的 EJB 4.3.2 在集群中的 EJB 对象 在 WebLogic Server 集群中,EJB 对象在服务器端的表示被一个复制敏感 (replica-aware)型根(stub)所取代。WebLogic Server 集群会为在其中的 EJB 对象在别的服务器上生成备份,叫复制(replica)。这样对客户端来说, 即使它所调用的 EJB 所在的服务器崩溃了,它还可以用备份。这种 EJB 对象 根 可以提供负载均衡和自动容错。例如一个客户端调用在某服务器上的 EJB,而这 时服务器崩溃了,EJB 对象根会自动把请求转到另一个正在运行的服务器上去。 EJB 是否使用复制敏感(replica-aware) EJB 对象 根取决于它是如何发 布的。 4.3.3 集群中的无状态会话 Bean 无状态会话 Bean 可以同时有集群敏感 Home 根和复制敏感 EJB 对象根。默 认的,WebLogic Server 支持 EJB 方法调用之间的容错。例如,如果在方法调用 110 完成后,或是连接服务器失败,这时会自动容错。但是,如果在方法处理的过程 中出错了,WebLogic Server 不会自动容错。 这种行为是为了防止在方法调用的时候,数据库会更新两次。例如,一个客 户端调用一个方法往数据库插入一条记录,在方法完成前 WebLogic Server崩溃 了,数据库就会被在一次方法调用中插入了两条记录。 如果一个方法能保证多次调用的结果也不会引起多余的更新,这个方法就叫 等幂(idempotent)的。对等幂的方法,WebLogic Server 提供在 weblogic-ejb-jar.xml 中的 stateless-bean-methods-are-idempotent 元素, 如果你把这个值设成 true,WebLogic Server会提供方法处理过程中的自动容错。 图 4-20 复制敏感根 客户端通过名字(naming)服务下载根(stub),这个根中包含一个复制代 理(replica handler),它可以按一定的算法来选择 replica。复制敏感根会 判断它接收到的异常(Exception)类型,如果是应用 异常或系统 异常,它不 会自动容错,因为这说明服务器仍存在,但是如果它接收到了网络/通讯 异常, 即使这是网络堵塞造成的,它也会认为服务器崩溃了,从而进行自动容错。 111 4.3.4 集群中的有状态会话 Bean WebLogic Server 5.1 只支持有状态会话 Bean 的 EJBHome 的集群。但是 WebLogic Server 6.0 已经支持有状态会话 Bean 的 EJBObject 的集群。 图 4-21 In-momery Replication - 1 WebLogic Server 采用一种叫内存复制(In-momery Replication)的技术 来支持有状态会话 Bean 的状态在集群中的复制。当客户端请求创建一个实例时, Home 根会在集群中选择一个服务器(Server1)来创建这个实例,这个服务器叫 作主服务器(primary server),同时,它也会选择另一个服务器(Server2) 在上面创建这个实例的备份,这个服务器叫作次服务器(secondary server)。 一旦创建完成,客户端的所有的请求都会被发到主服务器上的实例上。 112 图 4-22 内存复制 – 2 每当客户端提交一个事务来更新 EJB 的状态,WebLogic Server 会把 Bean 的状态复制到副服务器(secondary server)上的实例,来保证这两个实例的状 态是一样的。当主服务器(primary server)崩溃了,客户端的根会自动找到次 服务器上的实例来处理请求,这时,次服务器变成了主服务器,同时,会有一个 新的实例在第三个 Server 上生成,成为新的备份。如果主服务器仍存在,但是, 次服务器崩溃了,WebLogic Server 会重新选择一个次服务器。 为了使用有状态会话 bean 的内存复制(in-memory replication),必须 得保证这个 bean 在集群中的所有的 server 上都发布,而且使用相同的部署描述。 否则就无法实现。 默认的,weblogic server不支持有状态会话 bean 的内存复制。为了使用, 必须把 weblogic-ejb-jar.xml 中的复制类型属性 replicatin-type 设成 InMemory。 ... InMemory 内存复制的局限: 113 ·客户端提交了一个涉及到有状态会话 bean 的事务,但是主服务器 在 EJB 状态复制完成之前崩溃了,那么客户端的下一个调用将可能操作事 务提交前的状态。 ·客户端创建了一个新的实例并提交了第一个事务。但是主服务器在 EJB 的初始状态完成复制之前崩溃了,那么客户端的下次调用将无法定位 它的实例。这时客户端必须用可集群 home 根重新创建实例。 ·如果主服务器和次服务器同时崩溃了,客户端需要重新创建实例。 4.3.5 集群中的实体 Bean 实体 Bean能使用集群敏感home 根,只要把home-is-clusterable设成true 就可以了。而EJBObject的行为要看weblogic-ejb-jar.xml中的 cache-strategy (缓存策略)的设置。 实体 Bean 只支持方法调用之间的自动容错,不支持方法处理过程中的自动 容错。 读写 实体 Bean 在集群中和在非集群中几乎是一样的: ·在事务中多个客户端可以使用一个实体 Bean。 ·ejbLoad()总是在每个事务开始的时候调用(因为 db-is-shared 不能设成 true)。 ·ejbStore()按上面提过的原则调用。 而对只读 实体 Bean,在查找或新建实例的时候,客户端会得到复制敏感根, 它会作负载均衡和自动容错。每个Server上会保持Bean的数据以避免ejbLoad() 的调用。 114 图 4-23 集群中的实体 Bean 4.4 实体 Bean 的锁服务(Locking Service) WebLogic Server 容器支持数据库锁(Database Locking)和排他锁 (Exclusive Locking)机制。数据库锁改善了实体 bean 的并发访问。WebLogic server 把锁服务交给数据库去做。与排他锁相比,数据库锁能提供更好的数据 加锁的服务,在多数情况下,还提供死锁的侦测。 4.4.1 排他锁服务(Exclusive locking services) Weblogic server的 EJB 锁可以使用排他锁机制。如果使用排他锁,weblogic server 会在事务的过程中使用排它锁。当一个客户端使用 EJB 进行事务的时候, 别的请求这个 EJB 的客户端将被阻塞住,直至当前事务完成。 排他锁 是 Weblogic server 5.1和 4.5.1 的默认机制。这种机制提供对 EJB 数据访问的可靠性,避免了调用 ejbLoad()来刷新 EJB 的数据。但是,这种机制 115 并不是最好的并发访问机制,当一个客户端锁住一个 EJB 实例的时候,别的客户 端就无法访问这个 EJB 实例。 4.4.2 数据库锁服务 当使用数据库锁服务时,EJB 容器会对实体 Bean 的实例进行保存。但是容 器不会保存 EJB 实例在事务之间的中间状态,它只是在每次事务开始的时候调用 ejbLoad(),而将提交的请求直接发给数据库,由数据库来完成所有的加锁服务 和死锁的侦测。 数据库锁可以提供一个简单的方法来提高并发访问的性能,也提供了死锁的 侦测。但是,使用数据库锁需要对数据库的锁机制的详细了解。在不同的系统中 可能会影响 EJB 的可移植性。 4.4.3 设置数据库锁 你可以设置 weblogic-ejb-jar.xml 中的并发策略来指定使用数据库锁。 AccountBean Database 如果你没有设置并发策略,WebLogic Server 6.0 会使用数据库锁。 116 4.5 EJB 的环境,安全,资源和事务 这一节我们不再讲述任何关于 EJB 行为的知识,而是讨论和它们的部署描述 相关的一些很有用的知识,包括:环境(Environment),安全(Security), 资源(Resources),事务(Transaction)。 4.5.1 环境(Environment) 为了使 EJB 可配制性更好,更鲁棒,并且有更好的可移植性,Bean 的业务 逻辑的配置应该可以不通过更改代码来改变。环境为开发者提供了这种支持。环 境项是在运行时通过 JNDI 传递给 Bean 的参数,它在部署描述中定义和配置,通 过 JNDI 来访问。这样就可以不更改 Bean 的源代码也可以改变 Bean 的业务逻辑。 Any text goes here maxMessages java.lang.Integer 15 你可以在 META-INF/ejb-jar.xml 中定义零个或多个环境项,这是一个可选 的元素。它的类型只能有下列几种: ·java.lang.String ·java.lang.Integer ·java.lang.Boolean ·java.lang.Double ·java.lang.Byte ·java.lang.Short ·java.lang.Long ·java.lang.Float 那么,在程序中如何访问这些已经配置好的环境项呢?有两种做法: InitialContext ctx = new InitialContext(); Integer max = (Integer)ctx.lookup(“java:comp/env/maxMessages”); 117 或 InitialContext ctx = new InitialContext(); Context envCtx = (Context)ctx.lookup(“java:comp/env”); Integer max = (Integer)envCtx.lookup(“maxMessages”); J2EE 规范保留了 java:comp/env 作为各种资源的命名上下文(naming context)。如果你要查找部署描述中配置的资源,就必须以 java:comp/env 开 头进行查找。 4.5.2 资源(Resource) 在讨论之前,我们必须要理解几个术语: 1) 资源管理器(resource manager) 是对某个企业资源 的访问的对象。例如, java.sql.Connection,javax.jms.TopicConnection,java.net.URLC onnection,javax.mail.Connection 等等。 2) 资源管理器连接工厂(resource manager connection factory)是用来和资源管理器建立联接的对象,如 javax.sql.DataSource, javax.jms.TopicConnectionFactory, java.net.URL, javax.mail.Session 等等。 3) 资源管理器连接工厂引用(resource manager connection factory reference)是 EJB 用来引用连接工厂 (connection factory)的逻辑名 一个 EJB 可能会不在部署描述中配置资源,如一个叫“ds”的数据源 (DataSource),而是直接在代码中用 JNDI 去查找“ds”。这样会带来什么坏 处呢?一旦“ds”不存在了,比如改名为“datasource”,那么你必须去更改它 的代码,然后重新编译,再重新发布。而作为组件来说,它的适应性就很差了。 而你在部署描述进行配置又有什么好处呢? 118 图 4-24 DataSource 的例子 图 4-24 说明了 EJB 是如何得到数据源(DataSource)的: 1) 在发布的时候,数据源的引用被加到 JNDI 树上,在 java:comp/env 的上下文(Context)中 2) 当 EJB 需要数据库时,它会查找数据源的引用。 3) 这个引用自动取得数据源对象并返回。 4) EJB 从数据源得到连接(Connection)对象。 所以,在这种情况下,如果数据源的名字变了,只要改变部署描述中的配置 即可,而和代码无关了。 下面是一个数据源配置的例子。 119 图 4-25 ejb-jar.xml 图 4-26 weblogic-ejb-jar.xml 注意,在 ejb-jar.xml 中的是数据源的逻辑名,在程序中也是访问逻辑名。 在 weblogic-ejb-jar.xml 将逻辑名与实际的 JNDI 名对应。对EJB 本身来说,它 并不关心数据源的 JNDI 名,所有的操作都是通过逻辑名来完成的。 下面是访问数据源的代码: InitialContext ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/ExampleDSRef"); Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); …… 上面的指定为容器(Container),说明是由 WebLogic Server 自动进行安全认证。如果指定为应用(Application),说明是由 Bean 自己来进行认证: 120 InitialContext ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/ExampleDSRef"); Connection conn = ds.getConnection(user,passwd); Statement stmt = conn.createStatement(); …… 4.5.3 安全(Security) EJB 规范的作者为安全定了下列目标: ·减少开发者对应用进行安全管理的负担。 ·允许安全策略在发布的时候进行修改,而不是硬性的写到代码中去。 ·允许 EJB 可以在多个使用不同安全策略的服务器上移植。 当使用 EJB 时,一些间接的步骤会用来提供不同层次的安全管理: 1) 一个物理的 WebLogic Server 的安全域(security realm)被创建,来存放用户名,密码,和 ACL(访问控制表)。用 户登录 WebLogic Server 必须提供他的认证信息。而当 Java 程序从 JNDI 树上得到 InitialContext 时,它同时也会被 WebLogic Server 进行认证。同样的,WebApp 在 web.xml 声明它的安全限制,用户在 访问时也会被 WebLogic Server 检查。 2) 调用的线程会得到一个 Java 安全主体( security principal)的标识。主体是对一个线程的安全信任的封装。 3) 安全的组(group)或是角色(role)可以对应一个代 表唯一的安全权限的逻辑名。 4) 可以为 EJB 的每个方法指定可以调用该方法的角色。 每个 EJB 都会在运行态访问 EJBContext 对象,它包括了安全,事务和容器 的对象(如 Home 根)的当前信息。容器通过调用 setSessionContext(SessionContext ctx)来设置EJBContext,然后 EJB 才能得 到上述的信息。实体 Bean 和消息驱动 Bean 也有相应的方法。 121 图 4-27 EJBContext EJBContext 中的 isCallerInRole(String roleName)的目的是允许开发者把 那些不是很容易用部署描述的配置来实现的安全检查用代码来实现。这些检查可 能涉及的不只是 WebLogic Server中的用户,例如,可能和数据库中的一些表的 字段相关,或是和请求的参数有关。 EJB 可以用 isCallerInRole(String roleName)来测试当前的调用者是否是 一个指定的角色。 另外的 getCallerPrincipal()是得到调用者的认证信息。 一个 EJB 可以使用 Bean-managed security(Bean 管理的安全,不是很好) 或是 Container-managed security(容器管理的安全,比较好)。一旦设定了, 开发者仍然可以通过编辑部署描述来更改,这样节省了开发者去改代码的时间。 EJB 的行为围绕着由开发者定义的自定义安全角色(custom security role)。自定义安全角色通常是权限的垂直区域的集合。通过使用 ,EJB 可以在它的代码中连接这个引用。当 EJB 调用 isCallerInRole(String rolename)时,要使用中的子元素 的值。 这不是理想的,毕竟,一个稳健的实现应该支持容器管理的安全角色声明和 方法的权限。一个容器应该可以根据EJB 的方法、接口甚至整个EJB 来划分安全 界线。这可以用的子元素来完成。 122 元素可以赋给一个角色访问某个方法的权限。容器必须得 保证只有赋予权限的角色才能访问这个方法。 最后,在WebLogic Server里定义的用户和组必须映射到在部署描述中定义 的自定义安全角色。这使用 weblogic-ejb-jar.xml 中的 来实现的。 图 4-28 ejb-jar.xml 使用安全角色分三步。第一步,在ejb-jar.xml 的元素 中定义。 图 4-29 的语法 第二步,在中声明自定义安全角色,并用它来定义 方法权限。 123 图 4-30 的语法 图 4-31 的语法 第三步,在 weblogic-ejb-jar.xml 中加入用户和安全角色的映射。 图 4-32 的语法 124 下面是一个具体的例子: statefulSession …… golduser role …… …… role role statefulSession * 125 …… role mary …… 然后,客户端在取得 InitialContext 的时候必须传入 mary 的密码。 Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); h.put(Context.PROVIDER_URL, url); h.put(Context.SECURITY_PRINCIPAL, "mary"); h.put(Context.SECURITY_CREDENTIALS, "marypassword"); InitialContext ctx = new InitialContext(h); 而在 Bean 的代码中应该这样写: if(ctx.isCallerInRole("golduser")) //do logic here else //throw some exception 126 4.5.4 EJB 之间的互相调用 一个 EJB 可以像客户端一样来访问别的 EJB: ·在 JNDI 树上查找硬性写在代码中的 EJB Home 接口的 JNDI 名字。 ·得到 Home 接口 ·用 Home 接口来得到实例。 和上面提到的 EJB 对资源的调用一样,硬性的把 EJB Home 接口的 JNDI 名 字写在代码中会使 EJB 的代码随着它所访问 EJB 的 JNDI 名字的变更而变更。EJB 规范提供 EJB 引用来解决这个问题。EJB 引用是一个用来访问另一个 EJB 的别 名,它不是另一个 EJB Home 的绝对位置。它在 ejb-jar.xml 中定义,在代码中 通过 JNDI 命名环境来访问。但它只能引用会话 Bean和实体 Bean,不能引用消 息驱动 Bean。 在 ejb-jar.xml 中,可以使用来为任何一种 EJB(会话, 实体, 消 息驱动)增加引用。这个元素描述了目标 EJB 的引用名,Bean 的类型,Home/Remote 接口。如果要引用的 EJB 不在同一个 jar 文件中,用来引用。 图 4-33 的语法 下面是的例子: JspSessionEJB 127 ... ejb/HelloEJBRef Session HelloSLBean.HelloEJBHome HelloSLBean.HelloEJB ./example01-HelloEJB.jar#HelloEJB 其中 example01-HelloEJB.jar 是另一个 ejb 的 jar 文件,而 HelloEJB 是这 个 jar 中的。 相应的 weblogic-ejb-jar.xml 中的配置是: JspSessionEJB ejb/HelloEJBRef HelloEJBRef ... JspSessionEJB 中的名字和 ejb-jar.xml 的定义相对应, 中是这个 EJB 的 JNDI 名字。 在 Bean 的代码中是这样调用的: InitialContext ctx = new InitialContext(); 128 HelloEJBHome home = (HelloEJBHome)ctx.lookup("java:comp/env/ejb/HelloEJBRef"); HelloEJB hello = (HelloEJB)home.create(); //Do something with the bean... 这样,EJB 就可以用引用来得到另一个 EJB。 4.5.5 EJB 的事务 这一小节将讨论关于 EJB 事务的,开发人员必须要了解的概念,对 bean 管理的事务和容器管理的事务做一个比较,也会讨论 EJB 的六种事 务的属性及对 EJB 的影响。 一个 EJB 的事务的边界可以按三个层次划分:EJB 的客户端,EJB 容 器,EJB 本身。同时,事务分为由容器管理(CMT)和由 Bean 管理(BMT)。 如果使用 BMT,就得使用标准的 JTA Usertransaction 接口编程。 使用 CMT 时,开发者可以决定在调用哪些方法时需要事务,容器会在 方法调用之前开始一个事务,并在方法结束之后提交或回滚事务。 图 4-34 CMT 在 ejb-jar.xml 中,指明了 EJB 是使用 CMT 还是 BMT。但是,这个元素只能用于会话 Bean 或消息驱动 Bean,因为实体 Bean 只能用 CMT,所以这个值没什么用。可以有两个值, Bean(表示用 BMT)和容器(表示用 CMT)。如果使用 CMT,用 来定义方法的事务属性。下面是 的一个例子: 129 JspSession * Required 可以有六个可选的值: ·Never ·NotSupported ·Supports (默认值) ·Required ·RequiresNew ·Mandatory 每个值都指明了容器在方法调用时采用的行为,例如如果客户端初始 化事务时该怎么办,是不是一个新的事务必须开始。下面我们逐个来看。 如果一个 EJB 的方法的事务属性被指明为 Never(从不),则不能在 一个事务中调用这个 EJB 的方法。容器不会为客户端开始一个事务,而如 果开始了一个事务并且调用 EJB,容器会抛出一个 RemoteException。 130 图 4-35 Never NotSupported(不支持)会使客户端的事务在 EJB 方法的执行过程中 “挂”住,在方法结束后才能继续运行。就是说 EJB 的方法并不能加入客 户端的事务,无论 EJB 方法成功还是失败,都不会影响客户端事务的结果。 图 4-36 NotSuported Supports(支持)会使 EJB 的方法加入客户端开始的事务。但是容器不会位 客户端开始一个新的事务。如果客户端在调用 EJB 方法时并没有开始事务,EJB 不会加入事务,不会开始新事务。如果客户端在调用 EJB 方法时开始了一个事务, EJB 会加入事务。这是 EJB 方法的事务属性的默认值。 131 图 4-37 Supports Required(要求)会强制 EJB 方法必须在一个事务中执行,这个事务可能是 由客户端开始的,也可能是容器开始的。如果客户端开始了一个事务,EJB 的方 法会加入这个事务,如果客户端没有开始事务,容器会开始一个新的事务。 RequiresNew(要求新建)会强制 EJB 方法必须在一个新的事务中执行,这 个事务只能是容器开始的。如果客户端开始了一个事务,这个事务会在EJB 方法 执行的时候“挂”住,容器开始一个新的事务,EJB 的方法会加入这个新的事务。 如果客户端没有开始事务,容器会开始一个新的事务。 Mandatory(强制)会强制客户端必须传递一个全局事务给 EJB,这个事务 只能是客户端开始的。如果客户端开始一个事务, EJB 方法执行的时候会加入 这个事务。如果客户端没有开始事务,容器会抛出 TransactionRequired 异常。 图 4-38 Required 132 图 4-39 RequiresNew 图 4-40 Mandatory 在为 EJB 设计事务的时候要小心,下面是几点提示。 ·如果可能的话,尽量用 CMT。 ·你必须记住,设计得很糟糕的事务会大大的影响性能。当设计事务的范围 和长度的时候,不要划分得过分细,这样你的系统会因为忙于开始和提交事务, 而用于开始和提交事务的时间是很长的。另外,也不能把事务划分得过分粗糙, 这样一个事务的时间可能会持续很久,别的应用就无法访问被事务锁住的资源。 ·尽量避免使每个 Web 请求都开始一个单独的事务,可设想一下有 1000 个 并发用户的情况。 ·尽量避免一个事务跨越多个 Web 请求。第一,不能保证客户端一定完成所 有操作才退出;第二,会延长事务的时间,锁住有限的资源。 133 ·如果你的一次操作需要调用多个EJB 的方法,尽量把这个操作用无状态会 话 Bean 的一个方法实现,避免创建多个事务。 ·把要更新数据库的方法的事务属性设成 Required。 ·把只读的方法设成 Supports 或 NotSupported。 EJB 本身也可以控制事务是提交还是回滚。它可以通过抛出系统 异常,应 用 异常,或是调用 EJBContext.setRollbackOnly()来改变事务的结果。 EJB 可以调用 EJBContext.setRollbackOnly()强制事务回滚。当这个方法被 调用后,当前的事务不会立刻回滚,调用 EJBContext.setRollbackOnly()这个 方法的方法会继续进行下去并正常结束,只有当事务的开始者试图要提交事务 时,会提交失败,事务只能回滚。当然,如果 EJB 强制当前事务回滚,就继续执 行就没必要,最好在 EJBContext.setRollbackOnly()后直接返回。 如果 EJB 抛出一个系统 异常(任何 RuntimeException 或 EJBException), 正在执行的方法会立刻结束,这个异常会被抛给容器,容器会回滚它开始的所有 事务,并把这个异常再次扔给客户端。 如果 EJB 抛出一个应用 异常,正在执行的方法会立刻结束,这个异常会被 抛给容器,容器仍然会试图提交这个事务。只有在 EJBContext.setRollbackOnly()被调用的时候,提交才会失败。 如果一个事务会跨越多个 EJB 方法,那么即使这个事务很早就被 setRollbackOnly(),但是剩下的方法会继续执行。为了不浪费资源和时间,我 们希望剩下的方法不被执行,可以用 EJBContext.getRollbackOnly()来获得事 务是否被设成 rollbackonly(只许回滚)的标志位。 public void ejbMethod(){ if(ctx.getRollbackOnly()) return; //do you logic here } 如果你使用 BMT,EJB本身来划分事务边界。只有EJB 才能开始和控制事务, 如果一个客户端已经开始了一个事务,那么客户端的事务会在调用 EJB 方法的时 134 候“挂”住。BMT 给开发者最大限度上的自由来实现自己的事务控制,但是这种 控制得开发者自己来实现。 为了使用 BMT,开发者必须使用 javax.transaction.UserTransaction 接口。 再次声明,只有只有会话 Bean 和消息驱动 Bean 可以使用 BMT,实体 Bean 是必 须要使用 CMT 的。 WebLogic Server在启动时会把 javax.transaction.UserTransaction 绑到 JNDI 树上。可以用下面的代码来找到它: UserTransaction trans = (UserTransaction)ctx.lookup(“javax.transaction.UserTransacti on”); 图 4-41 BMT 如果想要开始一个事务,调用 begin()方法,后面执行的语句都会作为事务 的一部分。当用户调用这个事务的 commit()方法,表示事务成功完成;如果调 用 rollback(),说明有异常出现,事务回滚。也可以不用显式调用 rollback(), 可以用 setRollbackOnly()来防止事务成功提交,这不会使 rollback()立刻执 行,它只是置了一个标记位,说明由一个不能让事务成功的异常出现。 对于有状态会话 Bean 来说,不能把它的属性和与客户端的对话状态作为事 务的一部分,因为当事务回滚时,这些值是不会一起回滚的。但是,你可以用 javax.ejb.SessionSynchronization 接口来解决这个问题。 SessionSynchronization 接口由三个方法: 135 ·public void afterBegin() 这个方法会在一个事务开始之后立刻被调用。 ·public void beforeCompletion() 这个方法会在一个事务结束之前被调 用。这时还不能知道这个事务是否会成功提交。 ·public void afterCompletion(boolean committed) 在事务结束后会被 立刻调用。如果传入的 commited 变量的值为 true,说明事务成功提交,否则, 说明事务失败。 我们可以在 afterBegin()里保存原来的属性值,然后根据commited 来决定 是否要恢复原来的值。 String info = "123"; String temp = null; // Called by the application server right after the start of a new transaction. // If you store attributes that may need to be reverted, do it here. public void afterBegin(){ temp = info; } // Called immediately after the completion of a transaction. If the committed // variable is true, then the transaction was successful. If the committed value // is false, the transaction was rolled back. You can recover EJB state from // within this method if you need to. public void afterCompletion(boolean committed){ if(!committed) info = temp; 136 } //This method sets info = “456”,then setRollBackOnly public void Amethod(){ userTransaction.begin(); ...... info = "456"; ...... if(info.equals("456")) userTransaction.setRollBackOnly(); userTransaction.commit(); } 下面的图 4-42 是有状态会话 Bean 的状态图。这幅图和上面的有状态会话 Bean 的生命周期图有点不一样。处在一个事务中的有状态会话 Bean 是不能被钝 化的。 图 4-42 新的状态图 137 4.6 EJB 系统设计的考虑 如果你正在开发一个新的应用,你可能会想到 Enterprise JavaBeans(EJB) 适合于做什么。EJB 是近几年来的热门,很多项目都不由自主向它靠拢。项目开 始之际,在统一过程的初始阶段和进入细化阶段期间,对于软件项目要做重要的 架构性决策。在这些阶段期间,选择编程语言、工具和应用服务器都是所要考虑 的。关于应用服务器,EJB 技术可能是您最佳选择对象之一。EJB 是一项优秀的 技术,但它并不是可使用的唯一选项。那么如何知道对于你的项目,对于你的组 织什么时候它才是非常适合的呢?为了决定 EJB 技术是否适合于你的项目,需 要考虑以下问题。如果你对所有这些问题的回答都是肯定的话,那么 EJB 组件 就是你可以采用的合适技术。反之的话,别的技术可能更适合。 1) 你的系统是否有多种客户端访问? 通常,一个应用会有多种类型、需要访问相同信息的客户端。例如,一个应 用可能会有供外部客户访问的基于 web 的 HTML 前端,以及供内部人员使用的 更完整的用 PB 开发的应用前端。通常,这个问题是通过为同一应用编写两个共 享相同数据源(数据库表)的版本来解决的。但是,这种方法效率不高,无论是从 编程时间还是从同时发生多个数据库锁定时数据库的利用率来说。 EJB 技术的解决方案是将共享数据和商务逻辑集成到一套 EJB 组件中,以 供不同类型的客户端(如 servlet/JSP 和 应用)访问。EJB 组件控制着对后台数 据的访问,并管理着当前事务以及数据库的内部锁定。通过去除应用中的重复代 码,减少编写数据库控制逻辑的工作,这种方案降低了总的编程量。 在这个领域还有其它一些解决方案--比如,java 应用可以通过 HTTP 访问 java servlets,同时浏览器也可以通过 HTTP 访问 java servlets。这些解决 方案的问题在于:如果 servlet 是用来在浏览器中显示信息的,它就必须包含 一些表示层逻辑,这些表示层逻辑对于向另一个程序传递信息来说是多余的。因 此,你最终不得不采用两套部分重复的 servlets 来处理两种情况。此外,HTTP 138 不是程序间通讯的效率最高的协议。你必须设计能通过 HTTP 管道进行程序间信 息传递的数据格式--这通常或者是基于文本的格式,比如 XML(由接收端进行解 析,由发送端生成),或者是基于对象的格式,比如 java 序列化。两种格式都 需要大量的编程工作,它们都不如本地的 IIOP 速度快。 2) 系统是否需要对共享数据的读写进行同步? EJB 容器能自动处理这些复杂的共享数据同步问题。正如前面提到的那样, EJB 容器可以自己控制着对后台数据的同步访问,也可以把这项工作直接交给后 台数据库。EJB 也简化了开发者对事务控制的开发量,这不仅省去了编写数据库 控制逻辑的工作量,同时也保证了数据的一致性与正确性,从而降低了总的编程 量。 3) 你的业务是否要对多个数据库,消息队列等具有事务处理能力的资源进 行操作? 许多应用需要访问多个数据库或消息队列。例如,一个应用程序可能既要访 问来自中间层的 Oracle 数据库,又要向另一台机器上的 DB2 中插入一条记录。 这种操作必须作为一个原子来完成,并且数据完整性在不同数据库中也能得到保 证。这就涉及到分布式事务的问题。 过去,为了达到这个目的的唯一选择是采用事务监视器(TP Monitor),例 如 BEA Tuxedo。Tuxedo 是最好最快的 TP Monitor 之一。但是它需要用 COBOL、 C、C++ 等语言进行开发,并且开发的应用是平台相关的。WebLogic EJB 支持工 业 XA 标准,可以方便的进行两阶段提交,开发者不用对此操心。 4) 你是否要对你的资源进行安全控制? 某些类型的应用由于其安全性限制,使得以前它们很难通过 java 应用来实 现。例如,某些保险业的应用程序为了满足管理规定的要求,必须限制对客户数 据的访问。直到 EJB 技术出现后,才能够限制特定用户访问某个对象或方法。 139 在这之前,都是开发者自己完成安全控制的代码,开发者必须花很多的时间熟悉 各种安全技术。 EJB 技术可以在任何 EJB 上实施方法级的安全策略。WebLogic Server的用 户和用户组可以被授予或禁止对任何方法的操作权。而且这种安全策略可以通过 对部署描述配置来更改,不必修改 EJB 的源代码。 5) 体系结构是否有标准化、轻量化、组件化的需要呢? 对于许多有远见的公司来说,关键问题是要实现平台、销售商和应用服务器 设备间的相互独立。符合工业标准的 EJB 组件体系结构有助于实现这些目标。 在 WebLogic 上开发的 EJB 通常可以发布到其它类型的应用服务器上使用,反之 亦然。这已成为许多客户选择的战略发展方向。从短期看,利用一些可能优于标 准化的特性会更方便、更迅速,但从长远看标准化具有最大的好处。 另外,采用组件可以使代码的重用性大大增加,有利于将来的系统的扩展。 今天,一个公司的 IT 部门的灵活性与适应性是保持公司在市场中的竞争优 势的源泉。公司应迅速改进程序,以期对变化的市场环境做出反应,同时公司通 过更短时间内面向市场,比竞争对手更快的采取应对措施可以在竞争中取得飞 跃。通过设计能够适应更多的用户负载或事务需求的商务系统,IT 部门能够按 照市场需求规划部署。 EJB 能让一个公司具有更强的适应变化的能力。因为每一个基于 J2EE 平台 的产品都保证支持最基本的 J2EE 服务。公司可以只需构造一次编码良好,符合 J2EE 的程序,然后在部署时按应用环境做出决策。如果底层平台的功能、伸缩 性或可用性还不足以满足新的市场需求,用户可以有其他选择。如果客户的 J2EE 应用程序设计良好,并能符合标准,这个系统可以随着时间的推移通过更换底层 中间件、操作系统或硬件来进行放缩,却不会显著地更动应用程序。用这种方式 对未来 IT 投资的保护是很具吸引力的建议。对市场需求的反应时间缩至最短, 可以让公司以 INTERNET 所要求的那种速度采取行动。 140 6) 你的系统是否要 24 小时不停的服务? 很多系统要求不能停止服务,如银行,电信,火警等等,如果这种系统出现 故障,会照成巨大的损失。WebLogic Server 的 EJB 可以通过 WebLogic Server 的集群来做到自动容错。WebLogic Server 集群是一群协同工作的 WebLogic Server 的集合。它们可以进行负载均衡和自动容错。如果其中的一个服务器崩 溃了,其它的服务器会接管它的工作, 在这种情况下,EJB 是一个选择。WebLogic 支持其它服务器端 java 技术 (Servlets,JSP 文件)的自动容错。这些更面向表示层的技术与其说是 EJB 的 竞争对手,不如说是对其的补充。但是,由于 EJB 的性能较低,对开发者的要求 比较高,所以这个问题的答案只能作为选择 EJB 的参考。 相信这些问题对你会有所帮助。简单来说,如果你的系统只有一台服务器, 只需访问一个数据库,建议你还是使用 JSP + Servlet + JavaBeans 的技术,既 简化开发,又提高系统性能。如果你的系统涉及多个企业内部的资源或其它系统, 或者,考虑到系统的扩展性,可以使用 EJB。当然,具体的选择要根据具体情况 而定。在正式开发之前,建议你先写一个简单的 Demo,按照你系统的要求进行 测试,来检验一下,不要冒然动手,免得前功尽弃。 4.6.1 在 WebLogic Server 上使用 EJB 的考虑 要考虑的地方,我会用斜体字表示。这里就不说废话了,直接进入正题吧。 EJB 为了实现更好的组件管理和简单服务对开发者做了某些限制,在开发时 要注意: EJB 一定不要使用读/写静态字段。为此,我们建议对于 EJB class 中所有 的静态字段声明成 final。 EJB 一定不要使用线程锁这样的方式简单的同步多个实例的执行。 141 EJB 一定不要使用 AWT 函数去试图输出信息到显示器,或从键盘输入信息。 EJB 一定不要使用 java.io.package 来试图访问在文件系统中访问文件和 路径。 EJB 一定不要试图监听一个套接字,接受一个套接字连接或者使用套接字进 行多信道广播。 EJB 一定不要试图查询一个类来得到关于声明成员的信息,这是不符合 Java 语言的安全规则的。 EJB 一定不要试图去创建一个 Class loader,得到当前的 Class loader, 设置 Content class loader, 设置 Security manager,创建一个新的 Security manager,停止 JVM, 或者改变输入,输出,和错误流。 EJB 一定不要试图使用 ServerSocket 去设置 Socket factory ,Socket, 或者使用 URL 设置 Stream handler factory。 EJB 一定不要试图去管理线程。 EJB 一定不要试图去直接读或写一个文件描述符。 EJB 一定不要试图为了写挑剔的源代码去得到安全策略信息。 EJB 一定不要试图去调入本地库。 EJB 一定不要试图去增加访问那些适应 Java 语言的普通规则而对于 EJB 来说是不可用的包和类。 这些规则是因为 EJB 的实现方法决定的,不仅仅在 WebLogic Server上适用, 在别的 EJB Server 上开发的时候也不能违反这些规则。 142 4.6.2 远程对象 在设计分布式企业应用时,你必须考虑远程对象和它们的客户端之间在网络 传递数据的影响。因为网络传递会造成性能开销,所以从本地的客户端 (Servlet,JSP,EJB 或是别的对象)访问 EJB 要有效的多。而如果从远程访问的 话,客户端的数据要经过序列化,通过网络传给 EJB,反序列化三步,有些时候 还会使用效率较低的协议:SSL,HTTPS,T3S 等等,如果传递的数据量很大的话, 性能还会下降。 尽量增加在同一个 JVM 中的对象调用。如果必须调用远程对象,尽量减少调 用的次数和数据的数量。 因为 EJB 会使用大量的系统资源和网络带宽,你必须构建一些业务对象作为 数据访问对象(data access object)和值对象(value object)来改善这个问 题。数据访问对象是用来专门用来访问数据库对象,主要实现了查询,更新,添 加,删除等功能。值对象是一个存放数据字段的结构,并提供了简单 get/set 方 法来访问这些数据。 另外,你的应用可以专门构建一个 EJB 来作为客户端和 EJB 层中的其他 EJB 进行通讯的媒介。 4.6.3 继承 当构建共享代码的相关 EJB 的时候,使用继承是个好方法。但是,你必须了 解 EJB 实现的几个有关于继承的限制。 对 BMP 的 EJB,ejbCreate()方法必须返回 EJB 的关键字(primary key)类。 这个 EJB 的任何子类都不能有返回类型是不同的关键字类的 ejbCreate()方法。 这个要求十分严格,即使你返回的类是原来的关键字类的子类也不行。同时, ejbFindXXX()也有这个限制。 143 因为 AHome.create()和 BHome.create()返回不同的远程接口,所以你不能 使 BHome 继承 AHome。但是,你仍然可以使用继承来使用从父类继承下来的方法 或是被子类覆盖的方法。 4.6.4 引用 一旦客户端得到了一个 EJB 的 EJBHome 对象,它可以调用 getHomeHandle() 来得到一个对 EJBHome 的引用。getHomeHandle()返回一个 HomeHandle 对象,它 可以在后面得到同一个 EJB 的 EJBHome 对象。 客户端可以把 HomeHandle 作为一个参数传给另一个客户端,得到 HomeHandle 的客户端用这个 HomeHandle 得到对同一个 EJB 的 EJBHome 对象的引 用。客户端也可以序列化这个 HomeHandle 并把它存放在一个文件中,以便后面 使用。 默认的,WebLogic Server 会把它的 IP 存放在 EJB 的 HomeHandle 中。对一 些防火墙,会引起一些问题。 如果你的 HomeHandle 无法穿过防火墙找到 EJBHome,你可以: ·如果是 WebLogic 5.1 ,在 weblogic.properties 中加上一句 weblogic.system.enableReverseDNSLookups=true ·如果是 WebLogic 6.0,在控制台中选中一个服务器,在配置 Configuration 中选择 Tuning,把 Reverse DNS Allowed 选中。 这样,WebLogic Server 会把服务器的 DNS 名字而不是 IP 存放在 EJB 的 HomeHandle 中。 144 4.6.5 生命周期 实体 Bean 可以被多个客户端访问,但是在任何时候只能有一个客户端访问。 当两个客户端试图同时访问同一个 EJB 实例时(具有相同的 primary key),第 二个客户端会被阻塞住,直到第一个客户端完成操作。 有状态会话 Bean 的一个实例每次只能被一个客户端访问。在同一个 JVM 中 的多个客户端线程可以访问同一个有状态会话 Bean 实例,但是必须是一个一个 按次序来访问。EJB 规范规定,对有状态会话 Bean 实例的并发访问将导致 RemoteException 异常。 有状态会话 Bean 的限制对 WebLogic Server内部或是外部的客户端都适用。 如果多个 Servlet 访问同一个有状态会话 Bean,每个 Servlet 线程应该有它自 己得实例。 为了避免 RemoteException,每个 Servlet 应该把对 EJB 实例的引用存放在 在 service()(或是 doGet(),doPost(),具体看你用那个方法来提供服务)方法 中声明的变量中。 4.6.6 事务 数据库的事务是在一个线上系统的典型的最有价值的资源之一。当使用 WebLogic Server 中的 EJB 时,这些事务资源会因为它们和数据库的连接更为重 要。 WebLogic Server 可以用一个连接池(connection pool)来服务多个并发 的数据库请求。使用连接池的数据库事务的数量和时间大大决定了连接池的效 率。对于无事务的数据库请求,WebLogic Server 可以非常快的分配和回收数据 库的连接,所以另一个客户端可以使用同一个连接。但是,对有事务的请求,连 接会在事务的过程中被客户端独享。 145 为了优化你的系统的事务使用,尽量使用“inside-out”的方法来进行事务 划分——只要可能,事务应该在数据库内部开始和结束,只有在必需的时候才把 它拿到外面(客户端)来。 让数据库来管理事务。 许多 RDBMS 数据库为 OLTP 事务提供高性能的锁机制。在事务监控器(TP Monitor)的帮助下,如 Tuxedo,RDBMS 数据库可以管理多个数据存储之间的复 杂事务。如果你的数据库有这样的能力,就要尽可能的用它。永远不要阻止数据 库自动为事务化分界限。 使用 CMT,不要使用 BMT。 你的系统应该尽量少用 BMT,除非有特殊需要,还是用 WebLogic Server 的 CMT。可能要使用 BMT 的情况: ·你必须在一个方法调用中定义多个事务。WebLogic Server 是按方法来划 分事务边界的,一个方法定义一个事务。如果一个方法中需要多个事务,就得使 用 BMT。 注意,如果你的 EJB 在一个方法调用中定义多个事务,还不如把这些事务对 应多个方法,一个方法定义一个事务,然后就可以用 CMT。 ·一个事务要跨越多个方法。例如,一个方法开始事务,另一个方法提交或 回滚事务。通常来说,这种情况应该尽量避免,因为这需要对 EJB 的工作详细的 了解。如果是必需的,那么你必须使用BMT,你要协调客户端对这些方法的调用。 无状态会话 Bean 和消息驱动 Bean 不要用 BMT。 无状态会话 Bean 和消息驱动 Bean 不会保留和客户端的对话状态,所以不要 用 BMT。 146 不要让客户端来划分事务边界。 通常来说,无法保证客户端会长时间存在。如果一个客户端开始一个事务但 在事务完成之前退出了,会浪费 WebLogic Server宝贵的事务和连接资源。即使 客户端能保证不退出,根据用户的交互来提交或回滚事务也是不可接受的,因为 无法知道事务的持续时间。所以,尽量在 WebLogic Server或是数据库这个层次 来划分事务。 使用事务声明。 可以在 EJB 的部署描述中来声明事务的类型(如 Required,Never 等等)。 这样把事务的处理交给 EJB Container,而不用开发者来实现了。 4.6.7 持久性 Weblogic Server 5.1 的 EJB1.1 容器对实体 Bean 使用一个消极的锁机制。 当客户端在一个事务中调用 EJB 的方法时,WebLogic Server 会在事务未结束之 前对 EJB 或是方法加排它锁。别的客户端只有等这个事务结束后才能调用这个 EJB 或是这个方法。 EJB 2.0 容器提供了数据库加锁的机制。当使用数据库锁 服务时,EJB 容 器会对实体 Bean 的实例进行保存。但是容器不会保存 EJB 实例在事务之间的中 间状态,它只是在每次事务开始的时候调用 ejbLoad(),而将提交的请求直接发 给数据库,由数据库来完成所有的加锁服务和死锁的侦测。 数据库锁可以提供一个简单的方法来提高并发访问的性能,也提供了死锁的 侦测。但是,使用数据库锁需要对数据库的锁机制的详细了解。在不同的系统中 可能会影响 EJB 的可移植性。 4.6.8 资源 区分“EJB 需要”的资源和“EJB 实例需要”的资源。 147 在开发时,区分“EJB 需要”的资源和“EJB 实例需要”的资源是很重要的。 为什么?因为资源分配是比较消耗性能的,要尽量最小化资源分配。打个比方, 你必须区分是这个 EJB 的所有实例共享这一个套接口(socket),还是每个 EJB 实例都要有一个自己的套接口。 客户端和服务器上只放必需的文件。 建议根据“须知(need to know)”的原则来放置相关的文件。对客户端来 说,只放 Home 接口和 Remote 接口的类文件;而服务器上放 EJB 相关的类文件。 4.6.9 EJB QL WebLogic Server 支持 Enterprise JavaBeans Query Language(EJB QL)。 EJB QL是为 CMP 实体 Bean 定义查找(find)方法的语言。这种语言允许EJB 容 器来实现 EJB 的 find 方法。用 EJB QL 来定义 find 方法是 EJB 可以在多个容器 和持久管理器(Persistent Manager)之间移植。EJB QL 是一种像 SQL 的语言, 可以被持久管理器编译成数据库的目标语言。详细的信息可以参看 EJB 规范 2.0。 4.6.10 CMP WebLogic Server 6.0加入的对 CMP 实体 Bean 的关系(relationship) 的支持。这种 CMP 模式比原来 CMP 在功能上更加方便开发者。 使用 CMP,数据库的访问逻辑不用写在实体 Bean 里面,相反,由容器在运 行时候处理。容器会处理 EJB 的持久域(pesistent fields)和与其它 EJB 的关 系。在 EJB 发布的时候,容器可以根据部署描述生成数据访问的代码。详细的信 息可以参看 EJB 规范 2.0。 148 4.6.11 消息驱动 Bean EJB specification 2.0 结合了 JMS,定义了一种新的 EJB——消息驱动 Bean。消息驱动 Bean 是一个标准的 JMS 消息的消费者,它是一个无状态的组件, 当 JMS Queue 或 Topic 有消息的时候,EJB Container 会调用消息驱动 Bean 来 完成对消息的业务处理。 消息驱动 Bean 没有 Home interface 和 Remote interface,因此不能直接 被内部或外部的客户端访问,客户端想要和消息驱动 Bean 交互必须发一条消息 到 JMS Queue 或 Topic 去,WebLogic Server 会自动创建消息驱动 Bean 来处理 请求。 只有 Container 能直接和消息驱动 Bean 进行交互,创建实例并把 JMS 消息 传给它,消息驱动 Bean 模式的设计目标是为了开发可以异步处理 JMS 消息的 EJB,它的开发和标准的 JMS 消息的消费者很相似。 4.6.12 4Session Bean 什么时候用无状态会话 Bean,什么时候用有状态会话 Bean,是简单而又直 观的决定。尽管 Session Bean 从本质上来说是暂时存在的,但是有时候还是有 必要记住客户端的数据。这时你需要用有状态会话 Bean。如果你的业务逻辑是 一次性的,即你只使用你的逻辑一次就完成了,这时你用无状态会话 Bean。 Session Bean 是系统的业务逻辑的基础。 无状态会话 Bean 提供对系统数据的“粗糙访问”(coarse-grained access), 如一些用于计算的服务。这种 Bean 只是暂时的使用系统的内存,因为它不用保 存客户端的数据。无状态会话 Bean 支持完全的负载均衡和等幂方法的自动容错, 它是相对轻量级的组件。因不保存客户端的数据,Container 会在基于每次方法 调用的基础上给客户端分配处理请求的 Bean 实例。这意味着,少量的实例就可 以处理大量的请求,这和实体 Bean 相比,性能要好得多,每个实体 Bean 实例 服务一个客户端。 149 如果客户端需要调用多个实体 Bean 来完成一个任务,那么这个功能应该用 Session Bean 的一个方法来实现。 Session Bean 提供对系统数据的“粗糙访问”来实现应用的工作流。 在处理对内存特别敏感的操作时要小心,如列出所有记录,批量获取,批量 更新和预览等等。强烈建议用 Session Bean 来实现,而不要直接和实体 Bean 进行交互来实现,很耗内存。 批量操作应该用 Session Bean 的方法来实现。 上面提到的批处理一般是在一次数据库访问中插入或更新多条记录,这种操 作需要多条 SQL 语句被执行,应该用无状态会话 Bean 来实现,但是有时为了性 能上的考虑,会用数据库的存储过程来实现。 基于输入参数的计算应该用 Session Bean 的方法来实现。 如果要根据输入参数实现一套算法,而不需要对数据库进行访问,可以用无 状态会话 Bean 来实现。 在 Session Bean 里实现业务逻辑,在实体 Bean 里保存数据。 Session Bean 最好用来实现上述服务及其组合。如果要把所有的操作作为 一个事务的原子来实现,你可以在 Session Bean 的一个方法中实现它们,否则 你可以把这些功能分布在多个方法中。 一个比较好的经验是把一个任务中的多步操作封装在一个方法中完成。 Session Bean里包含业务逻辑,通过实体 Bean 来操作系统数据。一般实体 Bean 也有自己的业务逻辑,但是要限制实体 Bean 的业务逻辑以提高它的可重用 性,通常,实体 Bean 的可重用性要比 Session Bean 的高。 确保有状态会话 Bean 被发布到集群上的每台 Server 上。 150 为了能在集群中复制有状态会话 Bean 的状态,你必须把这个有状态会话 Bean 的类发布到集群中的所有 Server 上,而且要使用相同的部署描述,否则, 有状态会话 Bean 状态的内存复制无法完成。默认的,WebLogic Server 不使用 有状态会话 Bean 状态的内存复制,你必须修改 weblogic-ejb-jar.xml。具体的 修改见上文。 WebLogic Server 5.1 不支持有状态会话 Bean 状态的内存复制,这是 WebLogic Server 6.0 的新功能。 通过 Session Bean 来访问实体 Bean。 为了提高性能,要尽量减少网络通信。客户端可以只和 Session Bean 进行 交互,由 Session Bean 来和实体 Bean 交互,在服务器端完成复杂的操作,再 把结果返回给客户端。如果客户端直接和实体 Bean 交互,通过不停的调用 get/set 方法来完成业务逻辑,网络通信量是很大的。 写“聪明”的有状态会话 Bean。 当有状态会话 Bean 死亡时,它的状态也丢失了。可以使你的有状态会话 Bean 在死亡之前把它的对话状态保存下来。但是,保存在什么地方可以有多种 选择,要根据环境和对话状态而定。 考虑使用 javax.ejb.SessionSynchronization 接口。 当有状态会话 Bean 使用事务时,javax.ejb.SessionSynchronization 接口 可以帮助你在事务回滚的时候恢复原来的状态:afterBegin(), beforeCompletion(), afterCompletion()。EJB Container 会在适当的时候自 动调用这些方法。 对于存储过程的讨论。 151 一些公司多年来一直在使用存储过程(stored procedure),很大程度上是因 为它们可以帮助减少网络通信量,并提高分布式计算环境中的性能。通常,这些 过程包含涉及多数据库操作的重要业务逻辑。远程应用程序调用这些过程,在 DMBS 服务器上执行它们所包含的 SQL 语句。当然,过程结束时,所有结果都返 回给应用程序。 这些旧有存储过程对 Web 应用通常是有用的。但是在采用三层结构的时候, 常常会遇到这样的一个问题,要不要把存储过程的逻辑用 EJB 来实现?从三层结 构的设计目的来说,要把业务逻辑和数据访问尽量分开,而存储过程既包含了业 务逻辑又包含了数据访问,结构不清晰,不利于代码的重用,另外,存储过程一 般是和数据库绑定的,不利于数据库之间的移植。 但是,很多时候出于性能上的考虑,要充分利用数据库本身的性能优化机制, 会把业务逻辑放到数据库里做。而对一个时间很紧的项目来说,把存储过程的业 务逻辑在 EJB 中重新实现一遍,会花费不少时间,拖延了项目的进度。所以,究 竟要不要把存储过程的逻辑用 EJB 来实现,这得结合各方面的因素来考虑。如果 你不打算替换掉存储过程,你可以在 Session Bean 的方法中实现对存储过程的 调用。 4.6.13 实体 Bean EJB 2.0 加入了许多引人注目的变动,包括 CMP 组件模型中的一些变动和 一种新的 bean 类型,它们将增强您在开发应用程序时的灵活性和可移植性。其 中的大量更改都集中在一种新 CMP 组件模型的定义中。它完全不同于旧的 CMP 模型,因为它引入了一个全新的成员,即持久性管理器(persistence manager), 并引入了全新的方式来定义 Container 管理的字段,以及定义这些字段与其它 Bean 和从属对象的关系。 CMP 在 EJB 2.0 中发生了根本变化。在 EJB 2.0 中,Persistence Manager 在运行时自动处理 CMP 实体 Bean 的持久性。Persistence Manager负责根据一 152 种称为抽象持久性方案的新的 EJB Persistence Manager 协议,将实体 Bean 映 射到数据库。此外, 还负责实现和执行多种查找方法,这些查找方法均基于EJB QL 这种新型查询语言。 注意到以下事实是很重要的,即符合 EJB 2.0 规范的产品必须能支持 EJB 1.1 CMP 模型,又能支持新的 EJB 2.0 模型。虽然这两种模型并不兼容,但是 为了保证向后兼容性,就必须能支持 EJB 1.1 模型。 WebLogic Server 5.1 和 6.0 都支持 CMP1.1 和 CMP2.0。理解这两种 CMP 有 什么不同以及 CMP1.1 的局限,对更好的使用实体 Bean 是很重要的。这里会对 CMP1.1 和 CMP2.0 进行简单的比较,方便大家理解。 在 EJB 1.1 中,开发者负责将实体 Bean 的持久性字段声明为 Java 基本 类型或可序列化类型。下列示例显示了一个 AccountBean 类,它是按 EJB 1.1 定义的,带有几个 CMP 字段: public class AccountBean implements EntityBean { private EntityContext ctx; public String accountId; // also the primary Key public double balance; public String accountType; …… } 在 EJB 1.1 中,CMP 实体 Bean 的 部署描述提供 元素,用 以标识这个实体 Bean 中的持久性字段(persistent fields)。如下所示, 元素用来区分写入数据库的字段和不写入数据库的字段。例如,ctx 不是和数据库中的字段相对应的字段,所以不能用。下面是 EJB1.1 的 ejb-jar.xml 中的相应部分: 153 containerManaged …… Container java.lang.String False accountId balance accountType Container 提供者提供一种工具,用来将实体 Bean 的持久性字段映射到数 据库表中的列,通常一个实体 Bean 对应一个表。下面是 weblogic-cmp-rdbms-jar.xml 中的映射关系: 154 demoPool ejbAccounts accountId id balance bal accountType type 155 对基本字段如 accountId , balance, accountType 来说,很容易持久化, 因为它们能很容易的映射为 SQL 类型,如 VARCHAR,CHAR 和 DOUBLE。 但是, 如果 AccountBean 里包含了一个复杂类,并想把它为持久性字段,如 OwnerInfo, 就比较难于持久化。这种类被叫做 AccountBean 的从属对象(dependent object)。 public class OwnerInfo{ public String fristName; // also the primary Key public String lastName; public int age; …… } 在 EJB 1.1 中,没有标准的方法将可序列化的对象映射到关系数据库。虽 然 OwnerInfo 类有其自身的字段集,但 部署描述并没有提供一种机制,来将这 些字段映射到数据库表的列。在大多数情况下,人们期望将可序列化的对象(如 OwnerInfo)作为二进制类型(有时称为 blob 类型)存到某个数据库表中。 如果实体 Bean 的数据方案很复杂,例如,一个Account 可能有多个 Owner, 而一个 Owner 可能有多个 Account。这种情况往往可以形成关系数据库中跨几个 表的复杂对象图。EJB 1.1 中的 CMP 对实体 Bean 之间的关系支持的不是很好。 在 EJB 1.1 中,如果某个实体 Bean 准备维持与另一个实体 Bean 的关系,则 Container 会自动将 primary key或 handle 用作一个链接。与某些其它实体 Bean 的关系可能是双向的,或者要依赖于一些不易用 primary key 或 handle 来表示 的字段。CMP1.1 并没有很好的实现。所以,在用 EJB1.1 来实现实体 Bean 之间 的关系,一般用 BMP,由开发者自己在代码中实现。 CMP1.1 对 ejbFind()方法的实现并没有作规定,完全交给 Container 提供商 去完成,没有统一的标准。这样就使得你的 CMP 实体 Bean 在不同厂商的服务器 之间移植时,要把原来对 ejbFind()的描述替换成新厂家的表示语法。WebLogic 156 Server 在 weblogic-cmp-rdbms-jar.xml 中描述 ejbFind()方法,用的是一种叫 WebLogic Query Language(WLQL)的语法。下面是一个例子,用来找出 balance 比输入的数量大的记录。 findBigAccounts double balance $0)]]> 在 EJB 2.0 中,CMP 实体 Bean 和 Persistence Manager 之间的新协议, 使你能够在实体 Bean 中定义更复杂的、可移植性更强的关系,包括 Bean 与 Bean 之间,Bean 与从属对象之间,甚至从属对象与从属对象之间的关系。 Persistence Manager 是新加入到 EJB 发布过程中的。Container 厂商,或 专长于特定数据库的持久性的厂商,将能提供这种 Persistence Manager。其思 路是将用于管理 Bean 关系的机制从 Container 中分离出来,Container 只负责 管理安全、事务和资源。这种职责上的分离使不同的 Persistence Manager能够 与不同的容器一起工作。它也使实体 Bean 能在不同 EJB 厂商之间以及在各种 Persistence Manager 之间具有更强的可移植性。 在 EJB 2.0 中,Persistence Manager 能够根据部署描述,实体 Bean 的抽 象持久性方案和专门发布 EJB 的人完成的工作所提供的信息,生成 CMP 实体到 关系数据库的映射。但是,Persistence Manager 并不局限于关系数据库。也可 157 以为对象数据库以及遗留的系统和 ERP 系统(如 SAP)开发 Persistence Manager。 为了将 Persistence Manager从 Container 中分离出来,必须定义实体 Bean 与 Persistence Manager之间的协议。这个协议在新的抽象持久性方案中表现出 来。此方案是通过部署描述中一组新的 XML 元素和 CMP 实体 Bean 中的一组代 码习语定义的。在 EJB 2.0 中,CMP 实体 Bean 被声明为抽象类,它的持久性 字段和关系字段是使用抽象的读方法和写方法来访问的,而这两种方法的方法特 征则映射为部署描述中的特定元素。 在发布该实体 Bean 时,Container 根据部署描述和实体 Bean,来具体 实现此抽象实体 Bean 类及其从属对象类。具体实现将包括数据访问代码,此代 码将在运行时将实体 Bean 的状态读出和写到数据库中。在运行时,Container 使用由 Persistence Manager 工具生成的子类,而不使用开发者定义的抽象类。 为了使讨论更充实,这里提供一个 CMP 实体的示例,它更具体地说明了抽 象持久性方案是如何工作的。在 EJB 2.0 中,CMP 实体 Bean 被定义为抽象的, 而且它的持久性字段并不在 Bean 类中直接定义。作为替代,开发了一种抽象的 持久性方案,从而允许开发者间接地声明持久性字段和 Bean 关系。下面是 AccountBean 的一个示例,它使用了新的抽象持久性方案。请注意,该类中未声 明任何持久性字段。但是,对于每个持久性字段都必须有对应的 get/set 方法, 用 set 方法来修改,而用 get 方法来访问。 abstract public class AccountBean implements EntityBean { private EntityContext ctx; /** * container managed fields */ 158 abstract public String getAccountId(); abstract public void setAccountId(String val); abstract public double getBalance(); abstract public void setBalance(double val); abstract public String getAccountType(); abstract public void setAccountType(String val); …… } 在此 Bean 的 ejb-jar.xml 中,声明 CMP 的各个字段。 containerManaged …… Container java.lang.String False 159 2.x AccountBean accountId balance accountType …… CMP2.0 还提供了 EJB QL,用来说明 Persistence Manager应该如何实现 CMP 中的各种查找方法。EJB QL 以 SQL-92 为基础,可由 Persistence Manager 自 动编译,这使得实体 Bean 具有更高的可移植性,并且更容易发布。EJB QL 语 句是在 ejb-jar.xml 中声明的。使用 EJB QL 非常简单。可以把上面的 CMP1.1 的 findBigAccounts()方法用 EJB QL 声明: 160 findBigAccounts double ?1]]> 另外,CMP2.0 还提供了实体 Bean 之间关系的实现。如上面所说的 Account 和 Owner 的关系,如果它们是一对一或是一对多的关系,用数据库的两张表就可 以存储它们的数据,并用外键来对应它们的关系;如果它们是多对多的关系,则 需要三张表。上面我们说过,CMP1.1 不能很好的实现实体 Bean 之间的关系。我 们看一下 CMP2.0 的思路。首先,你要判断 Account 和 Owner 是一对一,一对多, 还是多对多的。这里假定是一对多的,一个 Owner 有多个 Account。数据库的表 结构如下: create table account (acct_id varchar(50) constraint pk_acct primary key, bal numeric, type varchar(50), 161 owner_name varchar(50)); create table owner (owner_name varchar(50) constraint pk_cust primary key, acct_id varchar(50), age integer); 我们要实现两个实体 Bean,一个是 AccoutBean,另一个是 OwnerBean。在 OwnerBean 里要定义两个抽象方法来对 Account 进行操作。 abstract public Collection getAccounts(); abstract public void setAccounts(Collection accts); getAccounts()可以获得和当前 Owner 拥有的所有 Account;setAccount() 可以对设置当前 Owner 拥有的所有 Account。这两个方法不需要开发者去实现, Persistence Manager 会根据部署描述自动生成。下面是在 ejb-jar.xml 中对这 两个实体 Bean 关系的描述。 Owner-Account Owner-Has-Accounts 162 one OwnerEJB-OneToMany accounts java.util.Collection Account-Has-Owner many AccountEJB-OneToMany 163 Owner 同时,要在 weblogic-cmp-rdbms-jar.xml 中指定外键的对应关系。 Owner-Account Account-Has-Owner owner_name owner_name 164 这样,只要调用 OwnerBean 的 getAccounts()方法就可以直接得到与之相关 的 Account 的信息,这一切都可以通过对部署描述配置来完成,极大的减轻了开 发者的工作量,而且方便 EJB 在不同的 EJB Server 上的移植。 注:由于篇幅的关系,未能给出实体 Bean 之间关系的详细代码,在这里我 深表遗憾。在 WebLogic Server 6.0 附带的样例程序中,有实体 Bean 一对一, 一对多和多对多关系的完整的源代码,有兴趣的读者可以参考那些样例。 好了,读完 CMP1.1 和 CMP2.0 的比较,你在使用实体 Bean 时会做到: 尽量使用 CMP 以减少开发量,少用 BMP。 使用 CMP2.0,不要用 CMP1.1。 使用 EJB QL,少用 WLQL。 读写 实体 Bean 构建了一个对细致获得(fine-grained)的数据访问和操 作的模型。它们把信息缓存在服务器的内存中,作为数据库的中介者,为客户端 提供想要的数据的对象视图。RW 实体 Bean 相对而言是重量级的组件,每个实 例可以为单一的客户端服务。 如果你在 EJBObject 这一层绝对需要自动容错或负载均衡,不要用 RW 实体 Bean。 通常来说,一个实体 Bean 应该代表一个独立的业务对象,有独立的标识符 和生命周期,可以被多个 EJB 或客户端使用。相反的,从属对象代表了和别的业 务对象的生命周期绑定的数据。从属对象最好用一个或多个 Java Class来实现, 饱含在与之相关的实体 Bean 中。例如,在一个用户管理系统中,每个用户都签 了一个合同,如果用户不存在了,合同也不会存在了。所以,合同是用户的从属 对象。在数据库中的合同的表应该用一个帮助类(helper class)来实现,而不 是一个实体 Bean,这个类叫从属类。 165 如果要用实体 Bean 来实现,你必须确保当用户被删除时,他的合同也被删 除。 一个有独立生命周期的实体 Bean 不应该被绑定到另一个有独立生命周期的 对象,或被它管理。 生命周期和别的对象相关的数据应该用从属类来实现。 只读 实体 Bean 是处理静态数据的好选择,它提供在集群环境中的自动容 错和负载均衡。 使用 RO 实体 Bean 来访问数据,要遵循下列原则: ·这些数据对你的业务来说必须是静态的。 ·可以被非 EJB 的外部资源修改,但是修改的频率不能高。 ·如果是被 EJB 修改,则所作的更新不需要立刻反映到客户端。(客户端可 以暂时容忍不同步的数据) 只有要缓存静态数据的时候,才用 RO 实体 Bean。 可能跨越数据库中好几张表的对象关系应该集中到一个实体 Bean。实体 Bean 应该管理一个业务概念的生命周期,包括它所有的相关对象。 因为一个实体 Bean 应该提供对应它的相关数据的统一的、集中的远程接口, 则远层接口中的方法必须包含业务逻辑,而不仅仅是对数据的读取。 实体 Bean 的数据操作需要封装一些业务逻辑。如果你的实体 Bean 仅仅是 单纯的 get/set 方法的集合,那么你要考虑你的设计是不是错了。 尽管把几个相关的表集中到一个 RW 实体 Bean 中是一个好主意,但是你也 要小心设计。如果每个用户都有一百个合同,当你访问用户的时候,把他的合同 166 信息全部取出,这种操作会在内存中保留着一百个合同的信息,对内存是一个大 的消耗,会对性能造成影响。另外,对合同信息的读取也需要更多的数据库操作。 不要过分的使用集中的功能,这样会很难使用。作为一个原则,最好一个实 体 Bean 不要超过有一个以上的从属对象。 如果你不需要在内存中对数据进行缓存,没必要使用实体 Bean,这将白白 消耗服务器的资源。 只在需要对部分或是全部的数据进行缓存的时候,才使用 RW 实体 Bean 来 访为和操作数据。 实体 Bean 提供的是对一个独立的业务对象的访问和操作。你不能构造这样 的数据访问模式:从实体 Bean X 访问实体 Bean Y。 实体 Bean 提供的对数据操作的范围应该仅仅限于这个实例本身的数据(包 括 Bean 和它的从属对象)。不要使你的数据操作涉及到两个以上的实例。 尽量不要有实体 Bean 之间的相互调用,好的设计模是完全可以避免这一点。 你不能试图把系统中的所有对象都用实体 Bean 来实现。通常,一些数据量 小的数据和某些数据的小子集不要用实体 Bean 来实现,用在网络传输上的开销 是不合算的。 在每次对 EJB 的调用中要获得尽量多的数据。 如果你的实体 Bean 只是用来读写数据,最好用 Session Bean或一般的 Java Class 通过 JDBC 来实现。实体 Bean 需要封装业务逻辑,例如,一个银行的系统 对个人和企业有两种不同的业务规则,你的代表客户账户的实体 Bean 就要实现 可以根据客户的类型,按照对应的规则来读写数据的功能。 实体 Bean 要实现对数据的验证和格式化数据。 167 实体 Bean 的数据来自于数据库。你应该尽量简单化和最小化对数据库的访 问,从而优化你的实体 Bean。通常: ·限制 EJB 数据的 join 操作。 ·避免耗时很长的操作,会引起数据库的磁盘读写。 ·尽量使 EJB 的方法返回多的数据,用来减少客户端与数据库网络开销。用 get/setAttributes()而不是 get/setAttribute()来减少网络传输。 优化实体 Bean 对数据的访问。 实体 Bean 必须任何状态改变的时候设置 isModified()标记为 true,如果 EJB 使用了 CMP,在 ejbLoad()和 ejbStore()中把这个标记设为 false,优化 Container 对数据的访问。EJB 在写回到数据库之前,ejbStore()会被调用,在写 数据库的时候如果发生异常,WebLogic Server 会认为 EJB 已经被更新,而不去 管这个标记位。 在适当的时候使用 isModified()。 4.6.14 消息驱动 Bean 消息驱动 Bean 是一种和 JMS 结合的 EJB,作为一个标准的 JMS 消息的消费 者。JMS 队列(Queue) 或 主题(Topic)接收到消息,容器会去调用消息驱动 Bean。消息驱动 Bean 会对消息的内容做业务操作。 在你想使用 JTA 事务时,可以用消息驱动 Bean 来替代标准的 JMS 的消息监 听者。 使用消息驱动 Bean 来取代标准的 JMS 的消息监听者的一个好处是容器会自 动为你开始一个 JTA 事务,并且消息的接收是事物的一部分。同时,别的操作如 168 数据库更新也可以加入到这个事务中,这是唯一把 JMS 消息的接收和别的 JTA 操 作加到一个事务中的方法。 消息驱动 Bean 没有 Home/Remote 接口,因此不能和客户端直接交互。客户 端只有通过向 JMS 队列或主题发送消息来间接和消息驱动 Bean 来交互。 4.6.15 C/S 接口 这一小节将讨论客户端代码(Servlets,JSPs 和 request handler(请求代理) 等) 和 EJB 服务层之间的调用,也会涉及到集群和性能优化。我们假定客户端是 用 JNDI 查找及 RMI 调用来和 EJB 交互的。 4.6.16 对 EJB 服务的访问 如果客户端需要和一个特定的实体交互,建议你的客户端用一个会话 Bean 来和实体 Bean 交互。尽管看起来有些浪费,增加了额外的网络开销,但是这种 功能的实现模式有更多的弹性,更容易改变。 4.6.17 EJB 服务的粒度(granularity) 这里的基本问题是:实体 Bean 应该怎样为它接口中操作数据的方法划分粒 度?每个属性都应该有 get/set 方法吗? 如果你为每个属性都创建一个 set 方法,会导致性能问题。客户端对几个属 性一起进行操作的时候,需要多次调用 EJB,如果你提供一个返回所有属性的集 合或子集的方法,客户端就可以减少对 EJB 的调用,从而减少网络开销。细致的 划分 get/set 方法会导致性能下降。 在一个集群的环境中,db-is-shared 必须被设成 true,这意味着从 RW 实 体 Bean 中获取数据必须开始事务。容器默认的会在每次读操作时同步数据库和 内存中的数据。细致的划分 get 方法会导致多次操作数据库,如果客户端要得到 一系列数据的话,就会引起性能快速下降。 169 ·客户端的 RMI 调用会把参数序列化,然后把这些参数发到 EJB 层。细致划 分的服务会导致过多的网络传输。 ·每次对 EJB 的调用都会使容器做一些操作,如安全认证。细致划分的服务 会使这些奢侈的操作过多的被执行。 细致的划分 EJB 服务的粒度会引起性能下降,这是一个不好的习惯。 所以,要定义一次就能对 EJB 所有或部分属性操作的方法。例如,一个实体 Bean 应该提供一个重载的 getRequiredData()方法,这个方法的不同版本可以获 得不同的数据对象(data object)。数据对象是用来在 EJB 层和客户端传递数 据的对象,它们很像 C 语言的结构 struct,是 EJB 的属性的集合。数据对象必 须可以序列化,这样才能在网络上传输。为了优化对数据的访问,数据对象不应 该有 get/set 方法,对数据的合法性验证及格式化应该在客户端或 EJB 中做,同 时作为数据对象的消费者不应该对它进行修改。 数据对象代表了没有行为的数据结构。数据对象的消费者不应该对它进行修 改。客户端和 EJB 应该尽量重用数据对象。 4.7 一个具体用例 讲了这么多,我们来看一个具体的例子。你要开发的是一个用户管理系统, 其中你要提供一项用户查询功能。这是一个只读操作,而且仅仅是把结果返回给 用户看,没必要在内存中缓存结果数据集(如果缓存的话,内存的消耗会很大, 尤其是符合查询条件的记录条数较多的时候),所以,应该用会话 Bean + JDBC 来实现。另外,这个操作和单个用户的数据没有关系,是所有用户通用的操作。 所以,使用无状态会话 Bean 来实现。 下面是用户的信息表,当然,为了简化起见,仅列出了几个常用的属性。 CREATE TABLE USR( 170 ID VARCHAR(12) NOT NULL, NAME VARCHAR(20) NOT NULL, AGE INTEGER NOT NULL, BIRTHDAY DATE NOT NULL, CONSTRAINT SQ_USR_SYS PRIMARY KEY (ID) ); 和这张表对应的,我们要写一个数据对象和一个数据访问对象。一般,数据 对象的命名是:TableNameData.java,数据访问对象的命名是: TableNameDAO.java。 //UsrData.java package usrbean; import java.sql.*; import java.util.*; public class UsrData implements java.io.Serializable{ public java.lang.String id; public java.lang.String name; public int age; public java.sql.Date birthday; 171 } UsrData.java 是一个简单的类似数据结构的类,它的各个属性对应了表中的各个列。 //UsrDAO.java package usrbean; import java.sql.*; import java.util.*; public class UsrDAO{ public void insert(Connection con,UsrData usr) throws SQLException{ String sql = "insert into usr values(?,?,?,?)"; PreparedStatement ps = null; try{ ps = con.prepareStatement(sql); ps.setString(1,usr.id); 172 ps.setString(2,usr.name); ps.setInt(3,usr.age); ps.setDate(4,usr.birthday); int i = ps.executeUpdate(); if(i != 1){; throw new SQLException("Cannot insert into usr where id = " + usr.id); } }finally{ ps.close(); } } public void update(Connection con,UsrData usr) throws SQLException{ 173 String sql = "update usr set id = ?,name = ?,age = ?,birthday = ? where id = ? "; PreparedStatement ps = null; try{ ps = con.prepareStatement(sql); ps.setString(1,usr.id); ps.setString(2,usr.name); ps.setInt(3,usr.age); ps.setDate(4,usr.birthday); ps.setString(5,usr.id); int i = ps.executeUpdate(); if(i != 1){; 174 throw new SQLException("Cannot update usr where id = " + usr.id ); } }finally{ ps.close(); } } public void delete(Connection con,UsrData usr) throws SQLException{ String sql = "delete from usr where id = ?"; PreparedStatement ps = null; try{ ps = con.prepareStatement(sql); ps.setString(1,usr.id); int i = ps.executeUpdate(); 175 if(i != 1){; throw new SQLException("Cannot delete from usr where id = " + usr.id); } }finally{ ps.close(); } } public UsrData selectByPK(Connection con,UsrData usr) throws SQLException{ String sql = "select id,name,age,birthday from usr where id = ? "; PreparedStatement ps = null; ResultSet rs = null; try{ ps = con.prepareStatement(sql); 176 ps.setString(1,usr.id); rs = ps.executeQuery(); rs.next(); usr.id = rs.getString(1); usr.name = rs.getString(2); usr.age = rs.getInt(3); usr.birthday = rs.getDate(4); return usr; }finally{ rs.close(); ps.close(); } } public ArrayList selectByName(Connection con,UsrData usr) throws SQLException{ 177 String sql = "select id,name,age,birthday from usr where name like '%" + usr.name + "%'" ; Statement sm = null; ResultSet rs = null; ArrayList data = null; try{ sm = con.createStatement(sql); rs = sm.executeQuery(sql); data = new ArrayList(); int i = 0; while(rs.next()){ UsrData record = new UsrData(); record.id = rs.getString(1); record.name = rs.getString(2); record.age = rs.getInt(3); record.birthday = rs.getDate(4); data.add(i,record); 178 i ++; } return data; }finally{ rs.close(); ps.close(); } } } 对于我们的例子来说,只要用到 UsrDAO.java 中的 selectByName()方法,这个方法是根 据输入的用户名进行模糊查询,再把符合条件的记录返回。这里有一个注意点,如果你的记 录很多的话,一般要进行记录的定量返回,比如每次返回十条记录;如果不这样做,大数据 量的网络传输会对性能造成很坏的影响。用于进行数据操作的连接对象由 EJB 分配,在 EJB 里释放,UsrDAO 不需要考虑这些,但是不要忘了把在 UsrDAO 中分配的 ResultSet 和 PreparedStatement 等释放掉。 在这里你可能有几个疑问:既然只要用到 selectByName()方法,为什么还要实现别的增、 删、改的操作?实际上,对于一个数据访问对象来说,它的功能恰如其名,是专门用来做数 据的访问的,它对应了特定表的增、删、改及查询的操作。你在实现其中的一个操作的时候, 不妨也实现其余的操作。你会发现你的 DAO 对象的重用性会非常高。 另外,你可能会问为什么这些操作都以 UsrData 为参数,而不直接用 String primarykey 来作为参数?这很大程度上是为了统一接口,方便开发。我们在上面讨论过 EJB 的数据对 象的作用,对普通的 Java Class 而言也是一样的。系统的性能是由设计架构决定的,这种参 数传递的影响是微乎其微的。当然,如果你的数据对像有几百个字段的话,还是直接用 String pk 吧。 //Usr.java package usrbean; 179 import java.rmi.RemoteException; import javax.ejb.EJBObject; import java.util.ArrayList; public interface Usr extends EJBObject { public ArrayList selectByName(UsrData usr) throws RemoteException; } Usr.java 是 UsrBean 的 Remote interface,只提供一个方法。 //UsrHome.java package usrbean; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface UsrHome extends EJBHome { Usr create() throws CreateException, RemoteException; } UsrHome.java 是 UsrBean 的 Home 接口,因为是无状态会话 Bean,所 以 create()方法只 能是没有参数的。 这里有一个专门用来调试的类,有时 EJB 会在自己的代码中声明一个 log()方法来输出 调试信息,这样代码的重用性不高。对于比较大的 EJB 的开发而言,最好把这项功能独立 出来。 package usrbean; public class Debug{ /*Print exception info*/ private static final boolean VERBOSE = true; 180 public static void print(Exception e){ if(VERBOSE) System.out.println(e.getMessage()); } public static void printStackTrace(Exception e){ if(VERBOSE) e.printStackTrace(); } public static void print(String msg){ if(VERBOSE) System.out.println(msg); } public static void print(int i){ if(VERBOSE) System.out.println(i); 181 } } 在 EJB 的代码中会用到这个类。 //UsrBean.java package usrbean; import javax.ejb.*; import javax.naming.*; import java.sql.*; import javax.sql.DataSource; import java.util.*; import java.rmi.RemoteException; public class UsrBean implements SessionBean { private SessionContext ctx; /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbActivate() { Debug.print("ejbActivate called"); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbRemove() { Debug.print("ejbRemove called"); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ 182 public void ejbPassivate() { Debug.print("ejbPassivate called"); } /** * Sets the session context. * * @param ctx SessionContext Context for session */ public void setSessionContext(SessionContext ctx) { Debug.print("setSessionContext called"); this.ctx = ctx; } /** * This method corresponds to the create method in the home interface * "UsrHome.java". * The parameter sets of the two methods are identical. When the client calls * UsrHome.create(), the container allocates an instance of * the EJBean and calls ejbCreate(). * */ public void ejbCreate () throws CreateException { Debug.print("ejbCreate called"); } /** * select records by user's name * if error occurs,return null */ public ArrayList selectByName(UsrData usr){ Connection con = null; ArrayList alist = null; UsrDAO dao = null; try{ con = getConnection(); dao = new UsrDAO(); alist = dao.selectByName(con,usr); }catch(SQLException e){ Debug.printStackTrace(e); Debug.print("sql error"); return null; 183 } catch(Exception e){ Debug.printStackTrace(e); Debug.print("else error"); return null; }finally{ try{ con.close(); }catch(SQLException e){ Debug.printStackTrace(e); return null; } } return alist; } /** * Get connection from data source * */ private Connection getConnection() throws SQLException,EJBException { Connection connection = null; InitialContext ic = null; try { ic = new InitialContext(); DataSource ds = (DataSource)ic.lookup("java:/comp/env/jdbc/dataSource"); connection = ds.getConnection(); } catch (NamingException ne) { Debug.printStackTrace(ne); throw new EJBException(ne); } catch (SQLException se) { Debug.printStackTrace(se); throw new EJBException(se); }finally{ try{ ic.close(); }catch(Exception e){ Debug.print("ic cannot close"); throw new EJBException(e); } 184 } return connection; } } UsrBean 有两个比较重要的方法,一个是 selectByName()方法,它对应着远程接口的业 务操作,另一个方法是 getConnection(),它从 JNDI 上查找数据源(DataSource),取得连接 (Connection)对象给 EJB 来作数据访问。 下面是 UsrBean 的部署描述。 <%@ page import=" javax.naming.*, javax.ejb.*, java.rmi.RemoteException, java.rmi.Remote, java.util.*, examples.xml.xslt.* org.xml.sax.SAXException "%> <% Content c = null; String content = null; try { // Contact the ContentBean container through JNDI. Context ctx = new InitialContext(); ContentHome home = (ContentHome) ctx.lookup("xml-xslt-ContentHome"); c = (Content) home.create(); 259 //get content from EJB content = c.generateContent(); String output = null; //determine client type, set "output" and contentType accordingly String clientType = request.getHeader("User-Agent"); if (clientType.indexOf("WAP") != -1) { output = "wml"; response.setContentType("text/vnd.wap.wml"); } else { output = "html"; response.setContentType("text/html"); } %> <%=content%> <% } catch (Exception e) { System.out.println("error: " +e); out.println("error: "+e); } %> 2.9 JAXP 可插件层的实现 在上面的一节中,我们已经介绍了 JAXP,WEBLOGIC 支持 JAXP1.1,提供了标准的 JAXP 的实现和 API。 WEBLOGIC SERVLET 的属性描述 WEBLOGIC 中提供了下列几个 SERVLET 的属性: Org.xml.sax.HandlerBase Org.xml.sax.helpers.DefaultHandler Org.w3c.dom.Document 在 ServletRequest 的对象属性通过调 setAttribute (SAX)和 getAttribute(DOM)的方法中解 析 XML 的文档。下列代码显示使用方法: request.setAttribute("org.xml.sax.helpers.DefaultHandler", new DefHandler()); org.w3c.dom.Document = (Document)request.getAttribute("org.w3c.dom.Document"); WEBLOGIC XSLT 的 JSP 标记库的实现 260 在 WEBLOGIC 中 JSP 标记库提供了简单的标记可以在 JSP 中通过 XSLT 实现 XSL 的 转换。当然,目前 WEBLOGIC 中只支持 Build-in 的 XSLT 转换器。JSP 标记库包含在 xmlx-tags.jar 中。开发人员可以很方便地实现通过 JSP 标记实现转换。 详细的例子可看 WEBLOGIC 软件中 XSLT 的例子。 可以采用配置解析器和转换器进行 XML 的登记 XML 的登记简化了重 XML 程序中分离出的管理和配置任务。使用管理控制台为 WEBLOGIC 配置解析器和转换器。在 WEBLOGIC 域中可以包含多个登记,而在每个 WEBLOGIC SERVER 中只有一个或没有登记。在使用中,可以利用 JNDI 寻找到登记,而 不需要初始化 XML 的解析器和转换器。 可以采用配置外部实体进行 XML 的登记 WEBLOGIC XML 支持通过 XML 的登记实现对外部实体配置。一个简单的例子是登记 一个用以确认 XML 合法性的 DTD 文件,可以通过系统来实现 DTD 的合法性检查的工作。 详细的实现和配置请看 WEBLOGIC 的文档资料。 全方位的 XML 支持 WEBLOGIC SERVER 是基于 J2EE 的 WEB APPLICATION SERVER。所以在开发、配 置和管理中,BEA WEBLOGIC 采用了 XML 全方位的实现。同时采用了很多优秀的 XML 相关一些协议,例如 Apache ANT 等等。 6.3 Weblogic Server JMS 3.1 MOM 与 JMS 如今,几乎所有公司内都拥有多种品牌的计算机,这是由于这些公司多年 来不断购置新设备或并购其它公司所造成的结果。对于公司的技术人员来说,要 想使公司业务的各部分在这种环境下协同运作是件困难而费时的工作。此外,企 业必须全力以赴,将所产生的无数信息转化为战略优势,而不是统一各种技术和 设备。各公司需要将企业内的各种应用系统集成,这常常涉及到供应商、合作伙 伴及其它企业。 应用系统的相互连接和集成意味着移动数据,把数据转移至适当的地方, 并在不同的应用系统和数据库之间正确转换数据。面向消息的中间件可在大数据 量、高性能业务环境中实现企业应用系统的自动集成。采用符合工业标准的集成 方式,可加快开发速度,减少维护,使应用免受网络与操作系统软件变动影响, 从而提高工作效率。当企业内的应用系统数量增加时,面向消息的中间件可成比 例地扩容,在不影响速度、数据量或性能的情况下满足不断增长的需要。 261 经常变更的繁杂的应用集成需求,通常需要增加新的应用系统;而且包 括业务规则的变更,管理要求的变更,以及由于并购而出现的应用增加等。 集成的业务系统中在系统主机、网络和数据库上可能出项多个故障点 (图:非正常条件下的可靠传输),如何保证数据在非正常条件下的可靠传输是 面向消息的中间件需要解决的重要问题。同时,由于用户的应用设在多个平台上, 因此而面临着可移植性的挑战。为了保护在原有系统上的巨大投资,用户需要一 个可靠而灵活的可移植解决方案,该解决方案应具备高大量数据分布处理和传输 能力、可靠的数据传输机制、应用可移植性、投资保护、简化应用开发。 面向消息的中间件(Message-Oriented Middleware 或MOM),正是为了实 现业务应用系统集成功能,使应用系统集成的实施、维护和扩充变得极其方便而 产生的。 面向消息的中间件的实现方式类似于邮递业务系统,如下所示: 图:非正常条件下的可靠传输 262 邮递业务 MOM 写信 建立一个消息 在邮局投递 发送消息 要求收取回执(可选) 设置可靠传输(可选) 经邮政路由到达目的邮局 通过可靠队列传输消息 接收者接收邮件 接收消息 邮局发送回执 发送确认 消息中间件通过类似邮递业务的机制实现提供企业数据的同步或异步传 输,通过消息中间件,一些原本互相孤立的业务组件可以组合成一个可靠的、灵 活的系统。 典型的消息中间件通常具有下述功能或特性: ·同步和异步消息传送:可根据需要选择最适合的方式 ·消息恢复服务:消息队列被存储在磁盘上,而不是存储在主存储器中。如果应用程序、 通信线路或系统平台发生故障,数据不会丢失,以待故障排除后发送 ·发布与订阅:可使一个消息同时发送给数个接收方而无需了解接收方的数目、位置或 准备状态 ·自描述消息:对所携带的数据进行描述 ·全局命名:全局命名使队列在网络范围内直观可见,程序发送和接收消息时无须考虑 队列的网络位置或识别符 ·消息选择:消息选择特性可使应用程序开发人员使用建立在消息类型、级别、发送源 及消息数据内容之上的选择过滤器,使应用程序仅处理那些符合选择标准(预先定义)的消 息 ·高效数据传输:单位时间内大量的数据传输量 ·高伸缩性:支持单一的服务器连接或并发连接 ·24 x 7 高可用性·监控实用工具:监视和控制运行环境,在消息处理期间显示和捕获 警告、错误及其它消息 ·应用开发工具:包括 API、消息模拟和捕获、调试功能 ·开放、传输独立性和平台独立性:应用程序和底层网络及操作系统环境无关,应支持 UNIX、Windows、VMS、OS400 和主机等众多操作系统,支持 TCP/IP、LU6.2、DecNet 等 众多网络协议,并且支持多种开发环境。 263 J2EE 是全新的企业级业务系统标准,为了在 J2EE 中实现传统的面向消息的 中间件的功能,JAVASOFT 定义了 Java 中访问消息中间件的接口——Java Message Service (JMS)。 JMS只是接口,并没有给予实现。实现JMS接口的消息中间件叫JMS Provider (如BEA WebLogic Server, IBM WebSphere, Oracle IAS和SUN Iplanet),这 样的消息中间件可以从Java通过JMS接口进行JMS服务调用,从而实现传统的面向 消息的中间件的功能。 3.2 WebLogic Server JMS JMS 的 API实现是与厂商无关的,用来访问消息接收和发送系统。类似于 JDBC (Java Database Connectivity)服务:JDBC 是用来访问许多不同关系数据 库的标准 API,JMS 则提供同样与厂商无关的访问消息服务的方法,以访问消息 收发服务。许多厂商目前都支持 JMS 标准,包括BEA WebLogic Server, IBM WebSphere, Oracle IAS和SUN Iplanet等。 BEA WebLogic Server JMS 使您能够通过消息收发服务(有时称为消息 服务程序或消息监控程序)从一个 JMS 客户机向JMS Server发送消息,并由JMS Server向另一个 JMS 客户机转发消息。消息是 JMS 中的一种对象,由两部分组 成:报头和消息体。报头由路由信息以及有关该消息的元数据组成。消息体则携 带着应用程序的数据。根据消息数据的类型来划分,可以将消息分为几种类型, 它们分别是:简单文本 (TextMessage)、可序列化的对象 (ObjectMessage)、属 性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage), WebLogic Server JMS 264 还有XML数据流 (XMLMessage)。 消息收发系统通常是异步的,也就是说,JMS 客户机可以向另一JMS 客户 机发送消息而不必等待回应。因此,这完全不同于基于 RPC 的(基于远程过程 的)系统,如 EJB 1.1、CORBA 和 Java RMI 的引用实现。在 RPC 中,客户机 调用服务器上某个分布式对象的一个方法。在方法调用返回之前,该客户机被阻 塞,该客户机在可以执行下一条指令之前,必须等待方法调用结束。在 JMS 中, 客户机将消息发送给一个主题或队列,而其它 JMS 客户机则预订或监听这个通 道。当 JMS 客户机发送消息时,它执行发送操作而不等待回应,然后继续执行 下一条应用指令。消息可能最终转发到一个或许多个客户机,这些客户机都不需 要作出回应。 虽然大多数 JMS 厂商都提供消息服务,将消息从发送者转发到接收者,但 生成消息数据和定义如何发送消息却是应用程序开发人员的职责。接收消息的应 用程序必须强健、安全、快速而且可伸缩;BEA WebLogic Server通过CLUSTER 方式支持消息传输的可靠和高效。 WebLogic Server JMS Cluster 265 WebLogic Server JMS Cluster机制具有以下优势: Cluster上多台服务器间队列或主题的负载均衡—— 系统管理员可以指定多台服务器共同运行JMS Server,并分别指定每台机器 所提供的消息目的(队列或主题),从而根据系统的情况指定每个服务器所承担 的负载 Cluster范围内的消息目的(队列或主题)透明访问—— 系统管理员通过在服务器上指定不同的 connection factory,从而建立到 不同消息目的(队列或主题)的连接,而这些connection factory可以部署到各 个服务器上。 应用通过Java Naming and Directory Interface (JNDI)找到connection factory并且创建到JMS Server的连接,每个JMS Server负责提供对某些目的地 (包括队列或主题)的服务,不能被本机JMS Server处理的JMS请求会被转发到 相应的服务器上。 可扩展性—— 在Cluster范围内负载均衡的实现。 支持多点传输,减少JMS Server需要发送的消息数量,JMS Server通过 multicast IP只向相关组发送一次消息,而无需关心有多少订阅者订阅了消息, 从而减少了系统资源消耗,提高了系统效率。 WebLogic Server JMS按传输方式的不同可以分为两类: Point-to-Point(PTP) Publish-Subscribe(Pub/Sub) Point-to-Point(PTP) PTP 是点对点传输消息,建立在消息队列的基础上,每个客户端对应一个消息队列,客 Point-to-Point Messaging 266 户端发送消息到对方的消息队列中,而从自己的消息队列读取消息。 Publish-Subscribe(Pub/Sub) Pub/Sub实现了消息向多个目的自动发布的机制,Pub/Sub通常是匿名的, 能够动态发布消息,Pub/Sub保证某个主题的所有发布者(Publisher)发布的信息 准确无误地发送到这个主题的所有消息订阅者(Subscriber)。 JMS 消息类型 JMS 消息由两部分构成:消息头和消息体。消息头包含消息的识别信息和 路由等信息,消息体包含消息的实际数据。 根据数据格式,JMS 消息体可分为以下六种: TextMessage 数据是一个字符串。 BytesMessage 数据是字节流。 MapMessage 数据是一系列的命名和值的对应组合。 ObjectMessage 数据是一个流化的 Java 对象。 StreamMessage 数据是 Java 中的输入输出流。 XMLMessage 数据是 XML 格式 JMS 消息优先级 邮递业务中有平信和特快专递两种,同样,JMS也可以根据消息的优先级将 消息分为0-9十个级别。0-4是普通消息,5-9是加急消息,0代表低优先级。JMS 保证高优先级消息快于低优先级消息到达。 JMS 扩展 WebLogic Server JMS 不仅支持 J2EE 的相关标准,而且还对标准 JMS 进行了以下扩展: Publish/Subscribe Messaging 267 支持 XML 消息 可以定义 Session 例外监听程序 设置或显示 session 中允许的异步消息最大个数 设置或显示当达到最大消息个数时多点传输策略 动态创建永久队列和主题 WLS60 与 WLS60 之前版本的 JMSMessageID 格式转 换 设置消息重发延时 设置消息发送时间 设置消息重发时间 JMS和其他J2EE API的关系 JMS 与 JDBC JMS 客户端可以使用 JDBC 接口,可以 将 JDBC 和 JMS 包含在一个事务里。这种包 含可以在 EJB 里,也可以直接调用 JTA(Java Transaction API)接口实现。 JMS 与 JavaBeans JavaBeans 可以用 JMS Session 发送接收 消息。 JMS 与 JNDI JMS 客户端通过 JNDI 调用 Webapp Server 中的对象 JMS 与 JTA(Java Transaction API) JMS 客户端可以用 JTA 启动事务。JMS Provider 可以选择是否支持分布式事务。 JMS 与 JTS(Java Transaction Service) JMS 可以和 JTS 一起组成一个分布式事 务,如将发送接收消息和更新数据库包含在 一个事务里。 JMS 与 EJB 对于 EJB 组件来说,JMS 和 JDBC 一样, 是一个很重要的企业级服务资源。可以在 EJB 直接调用 JMS 服务,或通过一个 JMS 客户端发消息异步调用 EJB 组件(Message Driven Bean)。 268 JMS实现流程 开发 WebLogic Server JMS 应用通常包括以下图示的若干步骤: 我们对建立JMS联接做一简要描述。 首先,需要通过JNDI找到WebLogic Server JMS Connection Factory,通过 WebLogic Server JMS Connection Factory创建java client端与JMS Server的 连接,在创建好的连接中再创建一个可用的会话(Session), 通过JNDI找到发 269 送或接收的目的队列(queue)或主题(topic),使用创建好的会话和目的队列或 主题创建消息生产者(producer)或消费者(consumer)对象,如果使用异步通讯 机制,需要事先指定消息监听方法,然后开始联接。 发送/接收消息 联接开始后,我们可以通过以下方法进行消息的发送或接收:、 发送队列: qsender = qsession.createSender(queue); qsender.send(msg); 接收队列: qreceiver = qsession.createReceiver(queue); qreceiver.receive(); 发送事件: publisher = session.createPublisher(topic); tpublisher.publish(msg); 接收事件: tsubscriber = tsession.createSubscriber(topic); Message msg = tsubscriber.receive(); 异步接收 WebLogic Server JMS 的消息接收可以有同步和异步 2 中接收方式,同步接收指接 收程序等待接收消息数据,在消息到达前,不进行其他操作。 异步接收指消息接收程序指定当消息到达时需要执行的业务逻辑,并继续进行自己 的其他操作,当有消息到达时,JMS 会自动调用预先指定的业务逻辑服务程序。 下面,我们通过一个接收消息的具体实例说明如何实现 JMS 异步接收。 接收方程序: public class QueueReceive implements MessageListener { public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory"; public final static String JMS_FACTORY="weblogic.examples.jms.QueueConnectionFactory"; public final static String QUEUE="weblogic.examples.jms.exampleQueue"; private QueueConnectionFactory qconFactory; private QueueConnection qcon; private QueueSession qsession; private QueueReceiver qreceiver; 270 private Queue queue; private boolean quit = false; public void onMessage(Message msg) { try { String msgText; if (msg instanceof TextMessage) { msgText = ((TextMessage)msg).getText(); } else { msgText = msg.toString(); } System.out.println("Message Received: "+ msgText ); /* 业务逻辑处理程序 */ if (msgText.equalsIgnoreCase("quit")) { synchronized(this) { quit = true; this.notifyAll(); // Notify main thread to quit } } } catch (JMSException jmse) { jmse.printStackTrace(); } } public void init(Context ctx, String queueName) throws NamingException, JMSException { …… …… 初始化 Queue 的相关变量; qreceiver.setMessageListener(this); /* 设置 Queue 的异步监听程序 */ qcon.start(); } public void close() throws JMSException { qreceiver.close(); qsession.close(); qcon.close(); } public static void main(String[] args) throws Exception { 271 InitialContext ic = getInitialContext(args[0]); QueueReceive qr = new QueueReceive(); qr.init(ic, QUEUE); // Wait until a "quit" message has been received. synchronized(qr) { while (! qr.quit) { try { qr.wait(); } catch (InterruptedException ie) {} } } qr.close(); } private static InitialContext getInitialContext(String url) throws NamingException { …… …… 返回 InitialContext } } 需要说明的是:我们在接收程序中的 onMessage 方法中,定义了接收到消息数据后 应执行的业务逻辑,这就是异步的消息接收机制。 JMS并发性 在 JMS 的设计和实现过程中,我们应该注意多消息通道同时传输时的并发性,注 意在 JMS 涉及的不同对象中,有些需要创建不同的实例以支持并发消息服务访问: connection factory 支持并发使用,允许应用系统以多线程的方式访问 connection factory 对象 Connections 支持并发使用,允许应用系统以多线程的方式访问 Connection Session 不支持并发使用,应用系统应创建独立的 Session 对象进行并发数据传输 message producers 不支持并发使用,应用系统应创建独立的 message producers 对象进行 并发数据发送 message consumers 不支持并发使用,应用系统应创建独立的 message consumers 对象进 行并发数据接收 destination 支持并发使用,允许应用系统以多线程的方式访问 destination 对象 JMS与Message-driven beans 下面我们对JMS与EJB的集成做一个简单描述。 EJB 2.0 以两种方式支持 JMS 的集成:作为一种 bean 可用的资源;作为 一个 MessageDrivenBean。当将 JMS 用作一种可用资源时,EJB 作为消息的产 生者或发送者直接使用 JMS API 访问 JMS 服务。这时,EJB 将消息发送给 JMS 的主题或队列。而 MessageDrivenBean 却是消息的使用者或接收者,它监听特 272 定的主题或队列,并处理发送给该通道的消息。 使用 JMS 使 bean 能够发送消息而不会发生阻塞。EJB 并不知道谁将收到 消息,因为它是将消息发送给某个主题或队列,而不是直接发送给其他的应用程 序。而其他的应用程序可以选择订阅该主题或接收该队列,并在接收到有关新消 息时自动执行预先定义好的业务逻辑。这样就有可以动态地修改应用系统中的业 务逻辑,使业务系统变得更加灵活。 Message-driven beans 即可以用来接收基于队列的消息,同时也可以用来接收基于主题 的事件,通过 Message Driven Bean 的配置文件进行指定。 在下述的 Message Driven Bean 的配置文件 ejb-jar.xml 中,指明 Message Driven Bean 所 监听消息类型为 Topic : javax.jms.Topic exampleMessageDriven1 examples.ejb20.message.MessageTraderBean Container javax.jms.Topic foo 在另外的 Message Driven Bean 的配置文件 weblogic-ejb-jar.xml 中,指明 Message Driven Message Driven Bean 273 Bean 的目的主题: quotes 在 Bean 的实现中,在 onMessage 中实现应用的业务逻辑: public class MessageTraderBean implements javax.ejb.MessageDrivenBean { public MessageTraderBean() {...}; public void onMessage(javax.jms.Message MessageName) {...} public void ejbRemove() {...} finalize{}; } 这样,就实现了对主题(或队列)的自动监听,并构筑灵活的业务系统。 6.4 Weblogic Server 的安全性 4.1 概述 在这一章节里,我们将了解如何通过 WebLogic 服务器的控制台来实现对用户安全系统 的配置、部署和设计。WebLogic 的控制台是一个功能非常强大、操作很简单的一个交互式 配置界面。使用 WebLogic 的管理控制台,我们可以为 WebLogic 的安全部署定义下列服务 的实现: 安全域(Security Realm) 用户和组(User & Group) 访问控制表和 WebLogic 服务器资源的权限(ACL) 安全套接层协议(SSL) 双向认证(Mutual authentication) 主机名校验(Host name verifiers) 自定义过滤器(custom filters) 等等。 由于 WebLogic 的安全服务相互之间都有一些非常紧密的关系,所以我们很难确定 从哪里可以开始进行安全服务的部署,因为他所有的操作并不完全是按顺序继续的。因此建 议大家按照如下的步骤对安全机制进行一些由浅入深的了解: 1:改变 system 用户的口令来保护 WebLogic 服务器的部署 2:为 WebLogic 指定一个安全域。缺省状况下,WebLogic 是采用一个文件域 来实现用户系统的,此外也可以为它定制不同的系统来实现安全机制,关于能够和 WebLogic 274 集成的安全系统,我们会在后面提到。 3:为安全域来定义用户和组。 4:为 WebLogic 的资源和用户以及组来定义他们的访问控制表。 5:我们可以通过安全套接层(SSL)来保证在客户端和服务器端之间的网络 连接的安全。在这里,WebLogic 服务器将通过一个由信任的授权机关签发的数字证书来向 客户端表达自己的真实性。安全套接层并不是必须的操作,可以根据我们的需求去选择。但 是 BEA 建议在进行关键业务的时候最好选择它。 6:此外我们可以为 WebLogic 服务器定义更进一步的双向认证,当我们将服 务器配置成双向认证之后,不仅客户端要验证服务器,而且服务器端也要验证客户端的真实 性。 下面我们将通过一步一步的学习来了解 WebLogic 的安全配置。 4.2 改变系统用户的口令 在最开始安装 WebLogic 的时候,系统就会要求你输入一个 system 用户的口令。 System 用户是 WebLogic 服务器的系统用户,级别相当与 UNIX 的 root 和 Windows NT(2000) 的 Administrator。但这个口令并不是不可改变的,处于系统的安全角度考虑,我们可能需要 每隔一段时间就更改以下 system 用户的口令,这可以通过 WebLogic 的控制台来完成。 为了改变 system 用户的口令,我们将进行如下的操作: 1:在控制台左端的树下方,点击 security 结点。 2:在改变用户口令这个表单的名字这一表格里,添入 system。 3:在‘旧口令’这个表格中,添入原来的口令。 4:在‘新口令’这个表格中,添入新的口令。 5:在‘确认口令’这个表格中,再次添入新的口令。 275 图 1 如何修改超级用户的口令 注意:在一个域中的多个服务器里,所有的被管理服务器(Managed Server)一定使用 和主管理服务器(Admin Server)相同的口令。 4.3 配置安全域 安全域(Security Realm)是 WebLogic 服务器中很重要的一个部分,所有的 用户和组系统都是基于安全域去实现的。WebLogic 服务器不仅提供一个缺省的文件域系统 来实现用户系统,而且还可以和多种不同的安全域进行完整的集成,如缓存域、LDAP 安全 域、Windows NT 安全域、UNIX 安全域、RDBMS 安全域、自定义安全域等。我们将在下 面的章节对几个比较典型的安全域进行了解。 a:文件域 在我们使用缺省的文件域之前,我们需要为它的属性进行一些配置,通过这些配置, 我们可以更好地去使用文件域。配置的位置见下图: 图 2 文件域的属性配置 其中每个属性的含义见下表: 属性 描述 Caching Realm 选择所使用的 Caching Realm,此属性必 须在设置了 Caching Realm 后才有效 Max Users 系统可以设置的最大用户数 Max Groups 系统可以设置的最大组数目 276 Max ACLs 可以设置的最多的权限控制的数目 注意:所有的配置将会被加入到当前域的 fileRealm.properties 文件中。为了安全起见, 我们可以在进行部署之前和之后对文件进行备份。 b:缓存域 缓存域是 WebLogic 服务器提供的另外一个用户域系统。它能够与文件域合作,记 录所有的成功与失败的操作到缓存里面去,从而来提高操作处理的性能。对于建立缓存域, 我们同样可以在控制台上进行操作。见下图: 图 3 缓存域的属性配置 每个属性的含义见下表: 属性 描述 Name 缓存域的名字,这个值是不可以改变的 Basic Realm 与缓存域相连的安全域的名字,这个值 我们可以通过下拉菜单来选择 Case Sensitive Cache 设定是否是大小写相关 成功建立缓存域之后,我们还可以为其设定更多的属性,由于篇幅原因,在此不一一列 出。 c:Windows NT 域 WebLogic 服务器的一个很大的特点是它可以和很多现有的用户域系统的集成,例 如最常见的 Windows NT 域,通过这种集成,我们可以将一些现有的用户域系统与 WebLogic 277 的安全域进行交互。在这里面,Windows NT 只提供用户系统,访问控制表(ACL)仍然由 WebLogic 服务器来实现(仍记录在 fileRealm.properties 文件里)。当你在 Windows NT 域下启 动 WebLogic 服务器的时候,你必须用 system 用户进入 Windows NT。同时你必须要在 Windows NT 的用户管理界面中新添 system 用户并将其加入管理组里。 在 WebLogic 服务器中建立 Windows NT 安全域非常简单: 1:在控制台左边选择‘安全’中的‘域’结点。 2:在控制台右边选择‘配置一个新的 NT 域’。则出现如下界面(见下图) 3:重启 WebLogic 服务器。 4:在前面提到的缓存域的配置中,加入刚才所建立的 NT 域。 这样,我们就可以使用 NT 域来代替 WebLogic 服务器缺省的文件域用户系统了。 图 4 NT 域的属性配置 其中各属性的含义如下: 属性 描述 Name 安全域的名字 Primary Domain 我们所使用的 NT 用户系统的主机名字 和端口号,可以选择多个主机。 d:UNIX 域 UNIX 域与 WebLogic 服务器的连接与 Windows NT 很类似,主要分为以下几步: 1:在控制台左边选择‘安全’中的‘域’结点。 278 2:在控制台右边选择‘配置一个新的 UNIX 域’。则出现如下界面(见下图) 3:重启 WebLogic 服务器。 4:在前面提到的缓存域的配置中,加入刚才所建立的 UNIX 域。 图 5 UNIX 域的属性配置 4.4 定义用户 用户指是 WebLogic 服务器的具体操作者,在 WebLogic 服务器里,有两个特殊的 用户: a:system system 用户是 WebLogic 服务器里拥有最高权限和级别的人。也 就是服务器的系统管理用户。 b:guest guest 用户是由系统自动提供的,对于一个没有提供认证信息的用户, 系统缺省地将其设置为 guest 用户身份。 在 WebLogic 服务器中定义一个用户的操作是非常简单的: 1:在控制台左端进入‘安全’、‘用户’结点。 2:在控制台右端‘新建用户’这个表单中输入‘用户名’,‘口令’,‘确认口 令’的信息。 3:点击‘建立’按钮,一个新的用户就建立了。如下图: 279 图 6 新用户的建立 同样,我们也可以在这个界面中进行修改用户口令和删除用户的操作,以及将用户锁定 和解锁等操作。 4.5 定义组 组是一群具有类似特征的用户群,在 WebLogic 服务器里,同样有两个特殊的组: a:everyone 任何一个用户,都是这个组的成员 b:Administrators system 用户是属于这个组的成员,这个组的成员都具备对服 务器进行启动、停止、维护等操作的能力。 在 WebLogic 服务器中定义一个组的实现也很简单: 1:在控制台左端进入‘安全’、‘组’结点。 2:在控制台右端点击‘新建组’这个按纽。 3:输入组名,点击‘提交’按钮,一个新的组就建立了。如下图: 280 图 7 创建一个新的组 此外,我们还可以在建立组的同时加入用户和子组。 4.6 定义访问控制表 在 WebLogic 服务器里面,一个访问控制表(ACL)定义了一个用户对某一个资源 所拥有的操作权限。每一个 WebLogic 服务器的资源都拥有一个以上的操作权限,通过 ACL, 我们可以在资源、用户(组)、权限之间建立一种有机的连接。下面这个表格列出了一些 WebLogic 服务器主要资源的操作权限: 资源 ACL 操作权限 WebLogic 服务器 weblogic.server weblogic.server.(servername) boot 命令行管理工具 weblogic.admin shutdown,lockserver, unlockserver 数据库连接池 weblogic.jdbc.connectionPool . (poolname) reserve admin 在 WebLogic 里面建立一个 ACL 是非常简单的: 1:在控制台左端进入‘安全’、‘ACL’结点。 2:在控制台右端点击‘新建 ACL’这个按纽。 3:输入 ACL 的名字,然后按‘建立’按钮。 281 4:点击‘添加新权限’连接。 3:输入‘权限’信息,点击‘提交’按钮,一个新的 ACL 就建立了。如下图: 图 8 如何建立一个新的 ACL 4.7 建立安全套接层 安全套接层是一个保证用户和服务器交流数据安全的服务,它的原理就是通过服务 器和客户端交换数字证书来确认对方的身份,在确认后通过新生成的密钥来对双方传输的数 据进行加密,以此来保证网络上传输的数据安全。 在 WebLogic 服务器里,我们可以通过它自己提供的一个证书服务来获得一些演示 版的证书。通常情况下,我们可以通过 http://localhost:7001/certificate 来访问这个服务, 生成和使用演示证书。 数字证书的格式有很多种,WebLogic 服务器能够识别和支持.pem 和.der 格式的证 书。 如何配置 WebLogic 服务器使其能够支持 SSL 服务是非常简单的。具体操作步骤如 下: 1:在控制台的左端,选择‘服务器’,‘我的服务器(这个结点的名字和实际建 立的服务器是有关的)’ 2:点击控制台右端的‘SSL’。 3:在各个表单中添入适当的选项,点击‘提交’。SSL 的配置就成功了。如下图: 282 图 9 SSL 的参数配置 下表是一些重要参数的描述: 属性 描述 Enabled 是否使用 SSL,缺省为使用 Listen Port 监听端口 Server Certificate File Name 服务器的证书文件名 Client Certificate Enforced 是否认证客户端,缺省不认证 缺省状态下,WebLogic 服务器会自动启动 SSL 服务,我们可以通过一个演示的操 作来了解 SSL 操作的进程: 1:以缺省配置启动 WebLogic 服务。 2:在浏览器中输入 https://localhost:7002/console。我们可以看到浏览器弹出如 下窗口。 283 图 10 浏览器弹出警告窗口 3:点击‘确定’,如果所有的认证都合格的话,将会自动进入安全连接页面,否 则浏览器会弹出如下警告信息: 284 图 11 浏览器报告证书存在问题 在认证过程中,客户端主要检查证书的三个信息来判断服务器端的证书是否符合要求: 该证书是否由信任的机构发行;该证书是否在有效期内;该证书的站点名称是否与我们真正 访问的站点名称匹配。如上图所示:证书的签发机构与有效期都得到浏览器的确认,但此证 书的名字与我们所访问的站点并不匹配。 4.8 建立双路认证 在通常情况下,我们只需要让客户端认证服务器端的身份就可以了。例如在线购物, 往往是客户更关心商家的身份是否可靠和值得信赖,而商家并不关心客户是否是一个他认证 过的值得信赖的客户。但是在某些情况下(如银行的在线服务),商家有可能要求客户本人 也提供商家可以信赖的数字证书,以保证交易在一个更加安全、可靠的环境下进行,此时就 需要用到双向认证。既不仅客户要验证服务器的可靠性,服务器也要验证客户端的可靠性。 实现双向认证的设置非常简单,只需要在 SSL 的配置中选择 Client Certificate Enforced 参数 就可以了。(见图 8) 4.9 口令保护 对于 WebLogic 服务器来说一个非常重要的问题就是如何对它的文件域系统进行安 全的口令保护。在 WebLogic 服务器 6.1 版本中,所有的口令都不是以明码的形式存在文本 中的,而是通过一个 SerializedSystemIni.dat 文件来进行加密保护。因此这个文件与当前域根 目录下的密钥文件必须得到很好的保护。通常情况下,我们建议通过进行备份以及将这个文 件的权限设成非系统用户的所有用户均不能访问以保证系统的安全。否则这个文件一旦遭到 破坏,我们将不得不重新安装 WebLogic 应用服务器! 关于 WebLogic 服务器用户口令,我们同样有很多的配置可以提供给系统管理员选 择: 285 图 12 用户口令的配置 主要属性的功能描述如下: 属性 描述 Minimum Password Length 口令的最小长度 Lockout Enabled 是否允许系统在客户进行不成功的登录 后对其进行锁定 Lockout Threshold 允许错误登录的次数 Lockout Duration 锁定的有效时间 4.10 小结 在这一章节里,我们主要讨论了 WebLogic 服务器的安全性、包括 ACL 和 SSL 等。 我们可以通过服务器所提供的服务来对用户进行完善的授权与认证,从而使系统的资源能够 得到有效的保护和利用。此外 WebLogic 服务器还能够与多种其他系统相兼容,能够与其他 的许多用户系统协同工作,从而大大减轻了开发者和系统管理员的工作量。 286 第7章 WLS 高级功能 7.1 WebLogic Server 集群 7.1.1 WebLogic Server 集群概貌 WebLogic Server 集群技术提供的先进的负载平衡和错误自动恢复的功能,给企业级的 关键应用带来了灵活的可扩展性和高度的可靠性。 可扩展性:从理论来讲,WebLogic Server 集群的能力是无限的。当需要的时候,我们 可以通过动态地增加服务器(Server)或者机器,在做集群结构的系统中分发请求、平衡负 载,满足不断增长的应用的需求。 可靠性:WebLogic Server 集群提供的容错的功能,提供了高度的可靠性。当应用运行 在集群的其中一个服务器上,如果这个服务器失败了,那么通过会话(session)状态复制, 它可以自动的转移到集群上另外一个可运行的服务器上。 7.1.2 什么是 WebLogic Server 集群 WebLogic Server 集群是由一组 weblogic 服务器组成,共同合作工作来提供一个更具可 扩展性和更高可靠性的应用服务平台,而对客户端来说它完全是透明的,就象运行在一个 WebLogic 服务器上一样。它提供软件一级的集群。BEA 的 WebLogic Server 提供基于软件 的集群技术, WebLogic Server 同时运行 在一组独立的服务器上,构成 Web 集群,保证在 WEB 及 Java 部署中的可扩展性及 高可用性及容错服务。 CLUSTERING Load Balancing Fault Tolerance 1.1.1.1.1.1 St 287 “集群”即在多台机器间复制应用表示层及商业逻辑的能力,使应用负载均衡地分布到 多台机器上。BEA 的 WebLogic Server 是唯一能够提供网页(Web-page)及 EJB 部件集群 的 Web 应用服务器。网页集群完成透明的复制、负载均衡及对为 Web 客户端生成的表示层 逻辑的错误恢复。部件集群完成复杂复制、负载均衡、EJB(商业逻辑)的错误恢复、并提供 对对象的状态恢复。 “容错”指 WebLogicServer 在下列情况下,为客户端提供透明的不间断服务: 服务器端系统崩溃 服务器由于运行错误或恶意中断造成运转不正常 由于不可靠的传输协议造成的消息丢失 网络连接中断,造成集群中的一部分无法正常工作 正常情况下,集群中的每个服务器会周期性的发送信号表明自己工作正常。一旦信号丢 失,这台服务器上的工作将自动转移到其它服务器上,不会造成用户应用的中断。 7.1.2.1 集群的价值 没有扩展的瓶颈; 没有单点失败; Browsers 1.2 Database BEA WebLogic Cluster DNS Round Robin Java Clients Replica-aware Stubs 288 对应用和开发人员是透明的; 集中监控和管理系统; 硬件、操作系统独立; 有多种供你选择的方案; 减少客户端和数据库之间的连接; 产品证明可行性; 支持 JNDI 和非 JNDI 的对象; 7.1.2.2 集群的意义 电子业务需求:可扩展性和 24*7 的可靠性 提供负载平衡、容错的功能。 7.1.3 在 WebLogic Server6.0 上集群新特征 可以和硬件的负载均衡集成在一起 对有状态会话 EJB 可以作到 home 一级和 object 一级的集群 可以做 JMS 的集群 HTTP 会话状态复制管理控制 在多个集群的环境下,可以共享同一个多目(multicast)地址,不会引起广播消息冲突。 要求:部署同类的集群对象 管理服务器的配置:所有 WebLogic Server 集群的配置都在控制台上进行。 7.1.4 什么服务可以做集群 •HTTP Session States •EJBs and RMI objects •JDBC Connections •JMS 289 主要有两类: HTTP 会话状态集群 通过会话状态复制的方法实现。 会话状态的保存有多种方式:内存(In-memory)、文件系统(filesystem)、数据库(JDBC)。 对象集群 实现 EJB 和 RMI 对象的负载平衡和错误恢复是通过复制敏感根(replica-aware stub)。 另外还可以提供 JMS 目的地和 JDBC 连接的集群。 在 WebLogic Server 中不支持集群的服务包括:文件服务(File services)、时间服务(Time services)、WebLogic 事件(Event)等。 7.1.5 WebLogic Server 集群配置结构 Managed Server 2 Local Logging Cluster Managed Server 1 1.2 anage Local Local Logging Administration 1.2.1.1.2 erver Domain Log Configuration Repository config.xml LDAP (future) DB (future) custom (future) GET / SET Get configuration at startup Critical Domain Notifications Log Critical Notification Monitor / Update 290 一个域(domain)是一个管理单元。管理服务器(Administration Server)能够管理所有 的被管理服务器(managed Server)。一个管理服务器负责维护域的稳定性,对所有服务器 的配置和跟踪与域相关的信息。被管理服务器用来执行所有的业务逻辑。被管理服务器在启 动的时候从管理服务器上得到配置信息。它可以独立于管理运行。所有的配置信息都保存在 文件仓库里(config.xml)。上面的图示表明:共有四个 weblogic server 实例, 其中一个作 管理服务器,另外三个作被管理服务器,其中两个被管理服务器配置成集群。 7.1.6 WebLogic Server 集群通信机制 一对多通信-多目通讯(Multicast)(地址范围:224.0.0.0-239.255.255.255) Multicast M1 M2 JNDI Cluster-wide “JNDI new/changed” 291 一对一通信-套接口(Sockets) 7.1.6.1 WebLogic Server 集群的特征和结构 7.1.6.2 JNDI 命名服务 7.1.6.3 集群服务-负载平衡 HTTP 会话状态的负载平衡:可以通过单独的负载均衡硬件或者用 WebLogic 代理插 件(proxy plug-in)内嵌的负载平衡的能力来实现。 集群利用 Web 服务器和 WebLogic 代理插件来分发对 Servlets 和 Jsp 的请求。代理插 Multicast M1 M2 JNDI HTTP/Object HTTP/Object IP Socket Cluster-wide 292 件只提供轮询算法。 集群采用硬件负载均衡的方案能够利用硬件支持的任何平衡算法。这些算法包括高级的 基于负载状况(通过监控每个独立机器利用率)的平衡策略。 7.1.6.4 集群对象的负载平衡 WebLogic Server 集群支持多种对象负载平衡算法。你选择的特定算法保存在在复制敏 感根(replica-aware stub)中。这些算法包括: Round-robin(Default) Weight-based Random 7.1.6.5 WebLogic Server 集群 HTTP 会话复制 对 Jsp 和 Servlet 的 HTTP 会话状态做自动的错误恢复。 对代理(proxy)的要求 WebLogic Server + HttpClusterServlet Netscape Enterprise Server + Netscape(proxy)plug-in Apache + Apache Server(proxy)plug-in Microsoft Internet Information Server + Microsofts(proxy)plug-in 对负载均衡器(Load Balancer)的要求 硬件必须支持 SSL 和消极 Cookie 保存。 对会话(Session)的要求 会话数据必须被流化 用 setAttribute()改变会话的状态 7.1.6.6 WebLogic Server 对象集群 复制敏感根(Replica-aware Stub) 根包含复制处理器(replica handler),复制处理器包含了负载平衡和错误恢复逻辑。 复制处理器能用不同的平衡算法:随机(random)、轮循(round-robin)、加权 (weight-based)、代码级(code-level)、基于参数的路由(parameter-based routing)。 293 7.1.6.7 EJB 集群描述 Server 1 Server 2 R 2 R 1 RH RAStub Replica-Aware Stub Replica Handler Replica Replica All EJB’s: home-is-clusterable Stateless SessionBeans: stateless-bean-methods-are-idempotent Stateful SessionBeans: InMemory 294 7.1.7 WebLogic Server 集群的基本体系结构 这是一个简单两层结构的 WebLogic Server 集群的应用部署结构,所有的 Web 应用都 部署在 WebLogic Server 集群中(包括静态 Http 、表示逻辑和对象),前面通过 web 服务 器接受请求,然后通过代理插件来分发请求。 7.1.8 WebLogic Server 集群的多层体系结构 Web Clustering (routing, load balancing, failover) Programmed Clients Web Server WL Plug-In Web Server WL Plug-In Servlet/ JSP/ EJB/RMI Web Services Servlet/ JSP/ EJB/RMI Web Services 295 这是一个多层体系结构的 WebLogic Server 集群:一层面向静态的 HTTP 请求,另外一 层面向集群的 EJB。有以下需求的 Web 应用,采用多层结构集群: 调用集群 EJBs 的方法时需要负载平衡 需要在 HTTP 服务器和应用 服务器之间提供灵活的负载平衡 需要更高可靠性 多层结构的集群比两层结构的集群的优点: EJB 方法的负载平衡 改善了服务器负载平衡的性能 更高的可靠性 更好的安全机制 Programmed Clients Servlet/ JSP Servlet/ JSP EJBs, RMI Objects EJBs, RMI EJBs, RMI Web Clustering (routing, load balancing, failover) HTTP routing Web Clients (via Web Server) Web Server WL Plug-In (NSAPI Web Server WL Plug-In (NSAPI Could also use router here Component, Object Clustering (routing, load balancing, failover) 296 7.1.9 WebLogic Server 集群的配置步骤 计划集群的体系结构 获得一个集群的许可证(License) 获得网络地址 创建 WebLogic Server 的实例 创建一个新的集群 配置复制组(可选择) 配置负载均衡硬件或者配置代理插件(可选择) 部署 Web 应用和 EJBs 启动 WebLogic Server 集群 在 WebLogic Server 控制台上配置集群: 需要注意: a. 在集群里的每一个 WebLogic Server 都需要一个单独的 IP 地址或者 DNS 名字,并且 运行在同一端口。 297 b. 在集群里的所有 Servers 必须在同一个子网内。 c. 组成集群里的每一个 WebLogic Server 必须是相同的版本。 7.2 WebLogic TUXEDO 连接器(WTC) 欢迎使用 WebLogic TUXEDO Connector(WTC)1.0。 WTC 为 WebLogic 与 TUXEDO 之间架起了一座桥梁,使 WebLogic 与 TUXEDO 之间互相调用成为可能。 WTC 示意图: 7.2.1 简介 7.2.1.1 WTC 基本特点 实现简单。WTC 不要求您修改现有的 TUXEDO 代码。Tuxedo 客户端通过 WTC 可以 直接调用 WebLogic Server 的 EJB。新创建的或者通过简单修改过的 WebLogic Server 客户端 同样能通过 WTC,访问 Tuxedo 的服务。 支持由 WebLogic Server 端发起的交易。 安全机制。 通过 eLink 与其他应用或主机互连。 7.2.1.2 WTC 支持平台 WebLogic Server 6.0 SP1 操作系统及其版本 厂商 操作系统 版本 Microsoft Windows NT 4.0 Microsoft 2000 2000 HP HP/UX 11 Sun Solaris 7 Sun Solaris 8 Red Hat Linux 6.2 TUXEDO8.0 操作系统及其版本 298 厂商 操作系统 版本 Microsoft Windows NT 4.0 Microsoft 2000 2000 HP HP/UX 11 IBM AIX 4.3.3 Sun Solaris 8 Red Hat Linux 6.2 eLink 操作系统及其版本 厂商 操作系统 版本 Microsoft Windows NT 4.0 HP HP/UX 11 IBM AIX 4.3.3 Sun Solaris 2.6 以上信息可能有所更新,详细信息可参见如下网址: http://www.weblogic.com/platforms/index.html 7.2.1.3 WTC 许可证要求 在不需要加密的情况下,使用 WTC 是不需要许可证的,当需要加密是,需要用到 TUXEDO LLE(链路层加密)许可证与 WebLogic Server SSL(安全套接口层)许可证。 7.2.1.4 WTC 相关文档 WTC 文档可通过以下网址得到: http://e-docs.bea.com/wtc/wct10/index.html 此网址还提供 PDF 格式文档下载。在这您还能找到 WTC 管理员入门与 WTC ATMI 程 序员指南,这两篇文档提供了 WTC 详尽的说明,另外,当您安装完 WTC 后,在您的安装 目录里有一个名为 examples 的目录,里面有 WTC 应用的实例,以方便您快速掌握 WTC 的 配置与应用。 7.2.1.5 WTC 的局限 不支持动态配置 不支持由 TUXEDO 端发起的事务 不支持会话通信方式 不支持 VIEW(TUXEDO 中的存储方式) 7.2.2 WTC 安装与配置 7.2.2.1 WTC 运行环境配置 TUXEDO 如果您的 TUXEDO 应用中已经使用了 TUXEDO/T DOMAINS(应用域),那么您只要 将相应的 WTC 作为一新的域加入到 TUXEDO/T DOMAINS 即可。 如果您的 TUXEDO 应用中还没有用到 TUXEDO/T DOMAINS,那么您首先要将您的应 299 用配置成支持域,再配置 DMCONFIG 与相应的 WTC 即可。 WebLogic Server 创建 Java 客户端与服务端 创建 WTC 配置文件(XML 格式) 在 WebLogic Server 中配置 WTC 7.2.2.2 WTC 安装 从 BEA 下载中心下载 WTC,WTC 可从 TUXEDO8.0 相关下载中得到,BEA 下载中心 网址是 http://www.beasys.com/download.shtml。 运行 WTC 安装程序 Windows NT/2000:运行 wtc10_win.exe UNIX:运行 wtc10_unix.bin 您将看到类似下图的提示,单击 Next 阅读许可证协议 接受协议,选择 yes 单击 Next 选择 Full Installation(完全安装) 300 单击 Next 选择 BEA home 目录 如果已经有 BEA home 目录,单击 Next 如果您想创建新的 BEA home 目录,可选择 Create a New BEA Home(创建一个新的 BEA Home 目录),再指定目录名,最后单击 Next 单击 Install(安装) 安装完毕后,单击 Done(结束) 7.2.2.3 WTC 配置 创建配置文件 用文本编辑器创建 XML 配置文件 您可以将 WTC 安装目录内的 examples\simpapp\bdmconfig.xml 文件作为模板,以次为基 础,创建您的配置文件 配置文件的组成 version:指定 XML 的版本号,如: DOCTYPE:文档类型,用于检测配置文件的正确性,如:<!DOCTYPE BDMCONFIG SYSTEM "file:c:\wtc1.0\weblogic\wtc\gwt\wtc_config_1_0.dtd"> WTC_CONFIG:WTC 配置文件主体,包含 BDMCONFIG 于 tBridge 两个子项 设置域运行环境 从控制台进入 WebLogic Server 应用目录 用文本编辑器打开 setenv.cmd,如 notepad 将 jatmi.jar 加入 CLASSPATH 环境变量,如:set CLASSPATH=%CLASSPATH%; D:\bea\wtc\lib\jamti.jar 保存文件 运行 setenv.cmd 301 更新 WebLogic Server 启动脚本 用文本编辑器打开 startWebLogic.cmd,如 notepad 将 jatmi.jar 加入 CLASSPATH 环境变量,如:set CLASSPATH=%CLASSPATH%; D:\bea\wtc\lib\jamti.jar 保存文件 运行 startWebLogic.cmd 启动 WebLogic Server 设置启动类 在 IE 的地址栏输入 http://127.0.0.1:7001/console,启动 WebLogic Server 控制 台,如下图所示: 选择 myserver->servers->myserver->logging,将 Stdout severity threshold 属性 改为 Info,单击 Apply,如下图所示: 302 选择 Deployments->Startup & Shutdown,单 击 Configure a new Startup Class,如下图所 示: 在 ClassName 栏内输入 weblogic.wtc.gwt.WTCStartup,在 Arguments(参数)栏内输入 BDMCONFIG=.\config\mydomain\bdmconfig.xml,TraceLevel=10000,最后选中 Abort startup on failure,单击 Create,如下图所示: 303 选择 Deployments->Startup & Shutdown,单击 Configure a new Shutdown Class,如下 图所示: 在 ClassName 栏内输入 weblogic.wtc.gwt.WTCShutdown,单击 Create,如下图所示: 304 重新启动 WebLogic Server,使以上做的配置生效,启动之后,您将看到类似如下的信 息: 如果您要卸载 WTC,您可以先将 Startup、Shutdown class 通过 WebLogic Server 控制台 删除,然后将 jatmi.jar 从 setenv.cmd 与 startWebLogic.cmd 脚本中的 CLASSSPATH 环境变量 中去掉,然后重新启动 WebLogic Server 7.2.2.4 WTC 实例 当您正确安装 WTC 后,在其目录下有一 examples 子目录,以下简单介绍其中的 simpapp 的执行方法与运行结果 根据 simpapp 目录中的 README.TXT 文件对 TUXEDO 与 WebLogic Server 做相应配置 启动 TUXEDO 服务 启动 WebLogic Server 应用 运行 run abc,WebLogic 客户端调用 TUXEDO TOUPPER 服务,其结果客户端如下所示: 305 WebLogic Server 端屏幕输出如下所示: 运行 tolower ABC,TUXEDO 客户端调用 WebLogic EJB,其结果客户端如下所示: 306 WebLogic Server 端屏幕输出如下所示: 以上对 WebLogic TUXEDO Connector(WTC)1.0 的特点、功能、支持平台、许可证要 求、安装、配置以及它的局限性做了较为详细的介绍,并且在最后给出了一个实例供读者参 考,以便读者动手配置运行时参照。相对来说 WebLogic Server 和 TUXEDO 相关信息,如 安装、配置提及得较少,有兴趣的读者可以从 http://e-docs.bea.com 网站下载相关资 料 。 7.3 WebLogic Server 性能调优 7.3.1 概述 应用系统的性能调整是一个非常复杂的操作,很多参数的配置和修改都会对最终系 统的性能产生很大的影响,在这一章节,我们将对一个应用系统各个方面的调整和配置做一 些简单的介绍。 总的说来,对于一个基于 WebLogic 应用服务器的应用系统性能有影响的设备主要 包含以下几个部分: 1:硬件 2:操作系统 3:Java 虚拟机 4:应用服务器 5:J2EE 服务 6:应用 下面我们将针对每一个组成部分做一些深入的了解。 7.3.2 硬件 对于硬件,由于它本身就包含多个部分,所以我们将对每一个设备进行讨论。 307 1:CPU 是一台计算机的灵魂。因此,采用数目更多、性能更好的 CPU 将会大大 提高系统的处理能力。 2:对于 WebLogic 应用服务器来说,采用 100M 的局域网络将是服务器的最小需求。 低于 100M 的网络带宽将为服务器的运行处理带来无法克服的障碍。 3:Java 应用服务器对内存的需求量是非常大的。 4:磁盘速度也是影响服务器的重要因素之一。 5:如果可能的话,将应用服务器与数据库服务器和 Web 服务器进行隔离可以获得非常 好的性能。(同时,必须要对独立的 Web 服务器进行性能的调优)。 除了这些必要的设备之外,如果系统中存在其他设备(如四层交换机),仍然需要对这 些设备进行相应的调优。 7.3.3 操作系统 由于操作系统的多样性,对于操作系统的调整并没有太多的通用规则。通常我们需 要按照操作系统所提供的文档对具体的某一个操作系统进行相应的调整。此外在 WebLogic 的在线文档中我们也可以得到 BEA 对具体的各个系统参数的要求。参见 http://edocs.bea.com/wls/。 尽管如此,还是有一些标准的参数是我们无论在哪个平台上都需要进行调整的。其 中包括: 1:TCP 参数,这些参数的调整需要根据相关系统的文档来进行。 2:操作系统所允许的最大线程数。 3:文件描述符的数目。 4:每一个用户进程所能占用的最大内存数。 通常情况下,后三个参数都是越大越好。 7.3.4 Java 虚拟机 对于 WebLogic6.1 来说,我们要求在 JDK1.3 以上的版本中运行(某些平台可能允 许客户端使用与服务器端不同的版本)。 此外,我们需要把 jit(Just In Time Compiler)打开并一直使用本地(native)线程 方式来代替 green 线程方式。(关于 jit、native thread 和 green thread 的详细内容,请参见 Sun 公司的 JVM 设计规范) 对于 Java 虚拟机,很重要的一个参数就是内存堆的尺寸,调整这个参数将大大影 响 WebLogic 应用服务器进行垃圾回收操作的速度。我们将通过启动 WebLogic 应用服务器 的命令行上的-Xms 参数和-Xmx 参数来设置它的最大值和最小值。通常,这个值设的越小, 垃圾回收的操作就越频繁,但每次操作的时间将变短;如果设的很大,则垃圾回收的操作次 数则减少,但每次操作的时间将变长。一般不要使这个值超过内存的大小。具体的大小,将 根据实际应用的情况来决定。 除了这些标准的参数外,不同平台的虚拟机还提供一些平台相关的参数来进行 虚拟机性能的改善。Sun、HP 都提供这样一些参数,相关资料可以在各个平台所提供的文 308 档中找到。 7.3.5 WebLogic 应用服务器 a:WebLogic 应用服务器的参数调整 对于 WebLogic 应用服务器,有一些重要的系统参数可以通过控制台来进行配置和 调整。调整界面如下图所示: 图 1 WebLogic 应用服务器的调优参数 下面我们对 WebLogic 应用服务器的参数逐一进行说明: 1:ExecuteThreadCount,这个参数表明在 WebLogic 应用服务器中开辟的线程数目。 这个值如果设置的太大,将会引起太多的内部损耗;而如果设置的太小,CPU 的能力将不 能充分利用。 2:NativeIO,如果 NativeIO 被启用,那么 WebLogic 应用服务器将使用 c 的代码 实现进行套接口(socket)的读取。 3:PercentSocketReaders,如果 NativeIO 参数被禁止后,那么这个参数的作用将非 常明显。这个参数的值是一个百分比,表明线程中用来读套接口(Socket)的比例。这个参 数的设置与应用的关系是非常敏感的,必须要在实际的应用环境中进行测试、分析和调整。 4:AcceptBacklog,这个参数用来设置等待请求的缓存大小,如果设置的太小,将 会抛出请求被拒绝的错误。 5:Use Java,这个参数的设置是在 SSL 配置界面上。当我们使用 SSL 的时候通常 要将这个参数选定。主要是因为 MD5 和 RD4 算法用 Java 来实现比较快,而 c 则在 RSA 上 有一些优势。 6:Reserve DNS Allowd,这个参数的设置将会降低系统的性能,如果不需要相应 309 的服务,我们可以禁止掉。 7:Enable Tunneling,这个参数的设置也会降低系统的性能,如果不需要相应的服 务,我们可以禁止掉。 b:WebLogic 应用服务器的群集 随着业务量的不断增大,应用系统所需要的硬件配置也越来越高。通常情况下,随 着机器配置的增长,性能价格比也会越来越低。在这种情况下,我们可以考虑使用多太小型 的、相对便宜的机器来完成一台大的机器所能够完成的业务量。这同样需要软件的支持, WebLogic 应用服务器就可以通过它的群集性能来实现多个应用服务器共同承担客户负载, 进行容错操作。以比较便宜的价格获得好的效果和更强的稳定性。WebLogic 应用服务器的 群集功能主要分为两部分: 1:负载均衡(Load Balance),所有的群集成员共同来承担客户负载,将所有的压 力共同分担。 2:容错处理(Fail Over),如果一个客户机非正常崩溃,那么所有在这台机器上 正在进行的业务将会不受影响地在其他的机器上继续进行,从客户的角度来看,不会发现后 台出现了任何变化。 对于一台配置比较高的机器来说,在同一计算机上启动两个 WebLogic 应用服务器 的实例有可能会比单个实例的性能有所改善,同时也增加了系统的稳定性。 c:如何来监控应用服务器的性能状态 对于监控 WebLogic 应用服务器的状态,我们可以有很多种方案进行选择。通常可 以通过能够对 Java 虚拟机内部资源进行监控的软件来实现。如 JProbe、Optimizit 等。 除了第三方提供的工具之外,WebLogic 应用服务器自己也提供一个简便实用的监 控界面。我们可以从控制台上连接过去: 1:在控制台左端选择‘服务器’,‘myserver’。 2:在控制台右端选择‘监控’,‘性能’。如下图所示: 310 图 2 WebLogic 的性能监测工具 从这个监控工具上,我们可以得到许多实时的信息: 1:Idle Threads,当前空闲的线程数目 2:Throughput,应用服务器的吞吐量 3:Queue Length,应用服务器队列中当前的排队客户数目 4:Memory Usage,当前内存占用的数目 此外,我们还可以通过界面上的 Force garbage collection 来进行强制的垃圾回收。 7.3.6 J2EE 的服务 对于几乎所有的 J2EE 的服务,WebLogic 应用服务器都提供了进行性能优化的空 间,下面我们将对几个重点的服务进行讨论。 a:JDBC 连接池 WebLogic 应用服务器提供一个对数据库的重要性能改进服务——数据库连接池, 通过这个带有缓存机制的服务,将大大改善用户访问数据库的性能而不增添任何代码上的复 杂度。对于每一个连接池,我们都可以从控制台上去看到他当前的状态,如下图所示: 311 图 3 连接池的监控界面 下面是对一些重要参数的描述: 1:Waiters,当前等待连接的用户数。 2:Wait Seconds High,目前等待的最长时间。 3:Waiters High,从启动以来等待的最大数目。 4:Connections High,从启动以来最大的连接数目。 这些值将有助于我们分析和调整连接池的数目以使其发挥最大的效力。 此外,还有一些连接池的配置参数可以影响他的性能: 5:Initial Capacity,最初的连接数目。 6:Maximum Capacity,最大的连接数目。 7:Refresh Period,检测连接的刷新时间。 8:Allow Shrinking,是否允许将长期不使用的连接关闭。 9:Shrink Period,进行 Shrink 操作的时间设置。 这些参数,在我们建立连接池的时候就可以设置,也可以随时修改,以适应实际系统的 需要。 b:Servlet / JSP 对于 Servlet 和 JSP 来说,我们进行性能调优需要在以下几个方面要进行注意: 1:选择一个速度比较快的 JSP 编译器,如 sj 等。 2:在群集环境下,尽量避免用 JDBC 的会话复制来代替内存中的会话复制。大量 无谓的数据库操作将大大降低系统的性能。 3:在编码上,要多使用 forward 来代替 sendRedirect,重新建立连接将占用系统的 资源。 312 4:慎重考虑单线程模式,因为单线程模式虽然能够保证绝对的线程安全,但是却 占用了更多的资源。 c:EJB EJB 可供调整的参数非常的多,而且不同类型的 EJB 就有着不同的性能参数。因 此在调整 EJB 的时候一定要非常注意,同一个参数对不同类型的 Bean 有着不同的效果。我 们先看一下对无状态会话 Bean 的监控界面: 图 4 无状态会话 Bean 的监控界面 下面我们对一些参数的功能进行简单的描述: 1:Idle Bean Count,当前空闲的 Bean 的数目。 2:Bean In Use Count,当前使用的 Bean 实例的个数。 3:Waiter Total Count,当前等待的客户总数。 4:Timeout Total Count,等待超时从而失败的客户总数。 5:Transactions Committed Total Count,提交的交易总数,也就是 Bean 被访问的次 数。 6:Transactions Rolled Back Total Count,回滚的交易总数,也就是 Bean 操作失败 的次数。 7:Transactions Timed Out Total Count,超时交易总数。 这些参数,对于我们调整服务器端的实例个数会有很大的帮助。 此外,我们还可以在 EJB 特有的配置文件 weblogic.xml 中设定例如启动时预置的实例 个数、交易超时时间等参数。这些参数对于不同类型的 EJB(无状态会话 Bean, 有状态会话 Bean, CMP 实体 Bean,BMP 实体 Bean, 消息启动 Bean)都有不同的设置,我们需要根 据各个 Bean 所提供的配置文件描述符的说明书来设定。 313 除了以上的参数之外,对于 EJB 的性能调优,我们还有一些基本的规则: 1:对于只读、而不进行写操作的数据,我们可以将相应的实体 Bean 设置成只读 属性。这将使实体 Bean 不去进行 ejbStore 的操作,大大节省了操作时间。 2:使用 is-modified-method-name 参数来限制方法调用时的 ejbStore 操作。 3:减少对实体 Bean 的频繁数据操作。 4:在业务需求允许的前提下,考虑将 EJB 的交易属性 TX Required 替换成 TX Support,这将减少系统的开销。 5:提高 max-beans-in-cache 来减少系统将 Bean 挂起的操作。 6:提高 max-beans-in-free-pool 来减少重新建立对象的操作。 d:JMS 对于 JMS 的调优,有以下几条规则可以参考: 1:考虑多建立一些目标(destination)。 2:由于 EJB 的容器对于组件的性能进行了优化,对于异步操作,可以使用消息驱 动 Bean 来实现。 3:考虑将信息永久存储以减少对内存的开销。 7.3.7 应用 应用的调整是多方面的,也是最不好掌握的一个部分。不同经验、不同经历的程序 员为同一需求写出的代码往往大相径庭。应用调优通常并没有一定的规则可以采纳。一方面 我们可以通过代码的调试找出错误所在,另一方面也可以通过一些间接的信息来找出应用的 错误。例如可以通过数据库的连接个数判断是否有数据库资源没有被释放,EJB 的实例数判 断是否有资源被死锁等。而这需要在不断的调试中积累经验。 7.3.8 小结 在这一章节里,我们主要讨论了关于 WebLogic 应用服务器的性能调整问题。但讨 论的范围并不局限在应用服务器之内,而是从硬件设备,操作系统一直到客户应用,都进行 了比较全面的讨论。这主要是因为一个大的系统中的任何一个环节都不是孤立的,所有的部 分之间都存在着密切的关系。总的来说,性能调优就是在对所有的问题进行评估后找出瓶颈 所在,争取让全部的资源都能够得到最大的、最充分的利用。 7.4 与其它系统的集成—WLI 7.4.1 WLI 简介 当今的企业高度依赖各种 Web 应用系统、无线应用系统、定制应用系统、套装应用系 314 统和遗留应用系统,实现部门和公司的业务目标。每种系统和应用的作用都是非常重要的, 它们负责支持企业运营,获取和使用有珍贵的客户数据,集中运营数据,将服务扩展到客户, 通过企业扩展与商业合作伙伴连成一体,以及提高整个过程的效率等。许多系统和应用都深 深扎根在现有业务流程中,而且占用了公司的大量开发、部署、培训和维护投资。 由于复杂程度高,而且支持这种环境需要很多资源,因此,虽然当今的公司都想提高企 业效率和获得投资回报,但他们面临的困难将越来越大。阻碍因素包括无法利用现有技能, 而且全方位实施需要投入大量资金购买资源。不灵活的业务流程无法随着业务的需求不断扩 展;当业务流程及支持业务流程的应用转向 Internet 时,无法充分利用遗留信息,这些都是 当今企业需要克服的问题。 借助新推出的 BEA WebLogic® Integration,在一个平台上就能为企业提供应用服务器、 应用集成、业务流程管理和 B2B 集成功能。这个企业级平台提供基于标准的“内在集成” 方法,使各公司能开发和部署新 Web 和无线应用,将它们与 ERP、CRM 和 MRP 等现有系 统快速集成在一起,理顺复杂的业务流程,并与商业合作伙伴连接在一起。 应用服务器与集成技术合并的时机已经到来。分析家对未来若干年的预测,开放标准的 快速开发,应用服务器作为电子业务的基石,以及对全面企业集成的需求,这些都是促成 BEA WebLogic IntegrationTM 推出的主要因素,统一的年代已经到来。 通过这节介绍,您将了解到关于 BEA WebLogic Integration 的以下问题: 集成在当今电子商务中的价值 平台相对于“点到点”解决方案的重要性 产品的技术概览 主要性能和好处 我们希望 BEA 客户、合作伙伴和潜在客户能够与 BEA 联系,探讨 BEA WebLogic Integration 能帮助他们如何帮助他们解决当今的业务问题,创造有价值的商业机会,并为未 来的发展奠定基础。 7.4.1.1 企业信息技术需求 在理想世界里,所有电子业务系统都应该作为一个整体协同工作。供应商、商业合作伙 伴、各部门、现有应用和新电子业务应用应该能相互操作并共享数据。这样不但能提高业务 流程的效率,还能减少人工步骤——对于重视赢利性和投资回报(ROI)的 Internet 经济来 讲,这一点尤为重要。无论所处的位置和所在的行业如何,所有公司都在寻求使之在竞争中 脱颖而出的新方式,他们希望获得统一的客户视图,以便快速满足客户需求,理顺企业级业 务流程,并且更加有效地与最有吸引力的商业合作伙伴协作。 但是,对当今的多数企业来讲,情况还十分复杂,各种系统相互独立,使企业无法享受 到真正集成式企业的益处。不但促进企业发展的各系统间的集成难以实现,而且需要多种技 术才能弥补缺口,如集成经纪人、定制钩和专用中件等。建立独立的应用并不难,真正的难 题是怎样使企业、系统、人员和流程协同工作。 315 图 1:多个部门、雇员、多种 IT 资源以及企业内外的客户的企业电子商务情景 如图 1 所示,多种起源和多方之间的顺利协作是很困难的。由于这些资源能够在复杂的 电子业务流程中互操作,因此以下列出的只是所遇到的困难的一部分。在阅读本节的过程中, 我们希望读者能积极思考,将这些典型集成问题与其机构内所遇到的具体问题进行比较。 内部系统所要求的交互。电子业务依赖多个系统,不但要支持内部的重点流程,还要支 持面向客户和商业合作伙伴的流程。这些应用和系统很少能独立运作,它们必须依靠其它应 用提供数据或企业应用需要的信息。例如: 电子营销解决方案需要从专有或打包 CRM 解决方案中获取信息,以便吸引新的潜在客 户和现有客户。 前端 Web 应用依赖资产数据保证按时履行客户定单。 除将多个福利提供部门和中间人的福利信息合并在一起外,员工福利门户还必须集中来 自内部人力资源系统的信息。 存货系统必须能与制造资源规划应用交流,以便在存货水平到达最低阈值时启动相应的 316 业务流程。 随着业务目标的改变和新 Web 应用的引入,现有系统必须经常维护而不是更换。SAP R/3、CICS/COBOL、Siebel 2000 或家庭成长遗留系统等将继续在电子业务中发挥巨大的作 用。问题是怎样实现集成、执行系统之间的数据映射以及解决防火墙问题——集成目标不仅 仅是简单的点到点集成,因而可能会大大增加 IT 部门的负担。 合作伙伴集成要求。几乎所有的机构都必须与若干家公司打交道,这样才能保持正常运 作,提供产品或分布服务。例如: 金融服务公司可以通过代理公司或经纪人网络销售产品和服务,每天(如果不是实时) 公布新政策或比率信息。 轮胎制造商将轮胎销售到多家汽车制造商和零售商,需要最新定单和预测信息才能满足 需求。 计算机硬件制造商从计算机芯片制造商那里购买芯片。同时,这些硬件制造商还向分销 商、分布商和最终客户提供最新产品信息。 可以通过电子通信实现业务合作伙伴协作行为自动化的机构将大大降低成本和提高机 构效率。另外,改善信息访问还能使企业更好地为客户提供服务,从而提高客户的保留率。 但是,这项工作并不容易,需要借助相应的技术为公司的现有系统和业务合作伙伴的系统提 供接口,并将正在使用的所有业务合作伙伴协议和标准集成在一起。 涉及电子交互和人力交互的复杂业务流程。例如,在 Web 站点上订购一台计算机可能 会涉及到存货检查、信用卡核实、批准电子邮件、建立定单和履行定单等。这个过程可以实 现很大程度的自动化,但是,无论自动化程度有多高,人仍然是电子业务过程中的主要因素。 从决策制定到处理例外,都需要许多系统、应用和人员协作才能实现多数电子业务流程。但 是,许多公司尚未找到解决这个问题的有效解决方案,因而必须依靠分立应用之间的硬编码, 或者容易出错的人工过程。 复杂的前端用户界面需求。需要一整套界面才能满足企业用户的需求,用户既包括系统 管理员和内部员工,也包括业务合作伙伴和最终客户。满足这些用户的多种需求所需的供应 机制包括应用、Web 界面和无线设备。 混合软件和硬件环境。多数企业都有多种平台,如 Unix、大型主机系统和 Windows 系 统,这些平台必须协同工作才能确保业务流程成功。即使企业目前已选择了有限数量的技术, 不再“多多益善”,我们也无法断定未来不会添加新系统,或者通过合并或并购产生多种系 统。 7.4.1.2 当前方法 如前所述,由于业务需求复杂多样,而且需要多种系统才能满足这些需求,因此企业必 须妥善解决集成问题。值得注意的是,这不仅是 IT 部门和 CIO 的问题,也是业务线员工的 317 问题,因为他们必须将技术作为业务增长的主要驱动因素。 到目前为止,许多公司都尝试用定制的“全方位”集成解决方案解决这些电子业务问题。 例如,他们可能通过购买许多现成产品来处理这种全方位集成需求,如将 SAP R/3 与遗留 CRM 解决方案和 Web 应用集成在一起。这种情况下,深入了解每种应用的开发人员小组或 外部厂商被集合起来,手工编写每种系统之间的定制集成代码。这种方法能暂时解决问题, 但是,业务流程、目标颖或待集成的许多应用中问题都没有解决。例如: 集成无效且存在问题。通常情况下,集成在一起的应用并没有从体系结构上相互集成在 一起,只不过能满足特定的业务需求而已。因此,必须经过新的研究才能实现这种集成,这 可能会影响应用的核心功能,而且需要专有技术,以便提供适当设计业务流程所必需的工具, 解决目标应用中出现的缺陷或性能问题。 集成的建立和维护太贵。将两个或更多的系统集成在一起一般需要深入了解每种目标系 统。典型情况下,可以利用专有技术进行定制编码,以此填补缺口。因此,IT 工人只有不 断学习才能建立和维护解决方案,而且服务的期限会延长,集成的成本很高。 新应用更难融入机构。引入的新应用必须集成到现有混合环境中。这时,必须为每种现 有系统分别执行集成,从而增加了定制集成点,不但占用很多资源,而且代码很少或根本不 会再利用。 必须建立多种关系才能形成集成解决方案。例如,机构必须与应用集成厂商一起处理 EAI 相关软件,与应用服务器厂商一起处理基本基础设施,与 B2B 集成软件厂商一起实现 跨机构协作,与业务流程自动化厂商一起设计和执行跨企业业务流程。 这简直是一个关系噩梦。关系和建立和维护是需要付出代价的,不同厂商之间的互操作 性很低,因此需要高度的厂商协作。在最坏的情况下,公司可能会发现自己需要将集成厂商 与其分立技术集成在一起。 到现在为止,每当企业面临新的机会时,唯一现实的选择是执行全方位集成。这些集成 是保持业务正常运作所必需的。但是,对企业来讲,这并非长期解决方案,事实上,这样可 能会将公司锁定到全方位集成的循环当中。如果某种解决方案能同时简化和统一集成过程— —但不涉及这种全方位集成——它将带来短期和长期改进。事实上,这种解决方案不但会帮 助各公司满足长期业务需求和缩短新计划的上市时间,还会降低总拥有成本,保护在新电子 业务系统上的 IT 投资。 7.4.2 BEA WebLogic Integration 应用服务器,如市场领先的 BEA WebLogic ServerTM,已经发展成现代电子业务系统基 石,但是,公司对电子商务技术的要求越来越高,因为他们已经意识到,真正的问题不是建 立应用,而是建立完全集成的企业。作为当今电子商务的基础,各公司希望应用服务器能够 在集成战略中起到更大的作用。 318 “应用服务器是很重要的,因为它是体系结构的基础。随着集成重要性的不断提高, 应用服务器的作用还将增大。从体系结构上看,当我们必须将一滩散沙组合起来的时候,它 们会使这项工作更加简单。” ——网上信用衍生物贸易公司,Creditex CTO,Jim Miller 资料来源:InfoWorld,2001 年 4 月 23 日 BEA 通过推出 BEA WebLogic Integration 解决了这个问题,这种基于平台的完整方法能 够: 开发和部署电子业务应用 将已经存在的应用与电子业务应用集成在一起 设计能跨越不同应用、不同部门和不同人员的商业流程 集成商业合作伙伴之间的 B2B 关系,包括供应商、分销商和分布商 BEA WebLogic Integration 是一种简单的统一平台,能扩展应用服务器的核心基础设施 和特性,将它们与用于执行复杂集成项目的综合解决方案合并在一起。这样产生的完整集成 解决方案使各公司能将应用管理的主要方面统一成“面向集成”的解决方案。 图 2:BEA WebLogic Integration 是企业开发、部署和集成的统一平台。 BEA WebLogic Integration 背后的哲学是,它以标准为基础,并提供完全可扩展的企业 平台。最后的结果是,企业的重点又回到手头的业务问题,而无需再担心基础设施或集成问 题,从而加速应用开发,缩短上市时间。基于标准的解决方案不但能提供近期价值,还能保 证为未来的 IT 计划增值。 7.4.2.1 BEA WebLogic Integration 的主要优点 BEA WebLogic Integration 的主要优点包括: 319 基于平台的统一解决方案。用于实现应用开发、应用集成、B2B 集成和业务流程设计 的基本平台出自同一家厂商。这样能减轻实现完整解决方案所需的关系负担,降低复杂性, 缩减成本,加强集成,而且无需“集成集成商”。 基于标准。BEA WebLogic Integration 基于 Java 2 Enterprise Edition(J2EE),这是建立 电子业务解决方案的事实上的标准。它还支持 World Wide Web Consortium(W3C),如 HTTP、 XML 和 Web 服务技术(包括 UDDI、WSDL 和 SOAP 等)。这些标准能为电子业务保证最 高的互操作性,因为它们几乎支持所有主要业界厂商。BEA 的承诺是,一切从客户利益出 发,不但遵守当前标准,还积极拥护新兴标准。 支持混合系统。由于 BEA WebLogic Integration 用 Java 技术写成,因而能在所有主要硬 件和操作系统上运行。这使得各公司能增加现有技术投资的价值。 支持多种用户界面。BEA WebLogic Integration 支持互多种前端用户界面互操作所需的 标准,包括应用、Web 浏览器、无线设备或其它定制界面。 功能丰富。BEA WebLogic Integration 为电子业务开发和集成需求提供完整的解决方案, 包括开发应用、设计业务流程、集成应用和执行 B2B 集成。 继续使用现有技能。标准平台意味着较低的培训和知识转移成本。开发人员还容易地可 以在项目之间转移,开发最佳实践,共享知识。最后,它还能有利于更容易地雇用新员工, 因为即将雇用的新员工可以借助对市场领先的 BEA 平台的先前经验了解系统的主要部分。 可重复的解决方案。应用集成可以外包,也可以内部开发,然后重复利用许多次,从而 降低成本,避免全方位集成。 企业级可靠性。BEA WebLogic Integration 是切实可行的技术,它以屡获大奖的 BEA 产 品为基础,这些产品已经过实践的检验,它们的扩展性、可靠性、容错性和安全性都很高, 适用于关键业务部署。 可扩展的平台。BEA 提供的平台可以从应用开发、部署和集成扩展到营销活动管理、 个性化和门户技术。 提供保护未来的解决方案。BEA WebLogic Integration 不是那种打包的盒装解决方案, 它灵活,基于组件,用户可借助业界标准技术通过编程扩展。不仅如此,还可以容易地修改 业务流程、添加新集成需求、增加新业务合作伙伴、进行合并和并购以及适应其它变化。由 于 BEA 提供市场领先的电子业务平台,客户不但可以得益于以与 BEA 技术的互操作性为基 础开发的各种 ISV 产品,还可以受益于利用切实可行的 BEA WebLogic 资源的众多系统集 成商。 7.4.2.2 BEA WebLogic Integration 的功能区 BEA WebLogic Integration 是一种统一的产品,共有四个主功能区。每个功能区可以满 足部门级别的独立需求,也可以作为完整的企业级解决方案使用。下面简要介绍每个功能区: 应用服务器。包含业界领先的符合 J2EE 标准的 BEA WebLogic ServerTM。提供开发和 部署新电子业务应用所需的关键基础设施和功能,包括安全性、容错性、消息传送和事务处 理。 应用集成。是基于 J2EE 连接器体系结构的新产品,能大大简化电子商务应用与现有企 业信息系统的集成,如 SAP R/3、Siebel、PeopleSoft 等。 320 业务流程管理。是一种全面的流程解决方案,使业务分析家和 IT 人员能设计、执行和 优化复杂的电子业务流程。能够在一个解决方案中集成各种业务流程,包括系统、应用和决 策支持人员。 B2B 集成。快速、安全地与业务合作伙伴连接在一起,以适应跨企业业务流程。它提 供多个合作伙伴连接选项和以流程为中心的 B2B 方法,不但能加速部署,还能随着合作关 系的发展不断修改。它利用领先的协议和标准,包括 cXML 和 RosettaNet 以及 SOAP、UDDI 和 WSDL 等 Web 服务技术。 7.4.3 应用服务器 企业级电子业务应用需要许多核心基础设施功能。开发这些服务可能非常复杂,从头做 起需要大量时间。例如事务处理管理、安全性、集群、网络透明性、遗留集成、多线程、持 久性、资源池、流程和 Web 服务。 BEA WebLogic Integration 内的 BEA WebLogic Server 功能遵守的准则是,通过划分和 攻克服务器方部署,将能够更快地实现企业目标。BEA 提供基础设施知识,使开发人员能 集中精力解决独特的业务问题,并生成新型应用。与内部编写整个解决方案或者购买现成产 生相比,这种方法要好得多,因为内部编写太昂贵,购买现成产品又不能通过扩展满足未来 需求。 BEA WebLogic Integration 应用服务器内部署的电子业务应用如图 3 所示。 321 图 3:部署在应用服务器内的电子业务应用 应用服务器提供可扩展的基础平台,使用户能在其上开发和部署自己的应用,或者部署 一系列现成应用。由于体系结构的可扩展性非常高,运行在应用服务器上的应用可以根据用 户的选择进行不同程度地定制。 7.4.3.1 应用服务器概览 应用服务器由三个主要部件组成:容器、管理控制台和命令行工具。 容器指部署的应用所在的运行环境。容器使用业界标准 Java 2 Enterprise Edition(J2EE), 作为服务器方开发的编程模型。J2EE 是一套规范,用于用 Java 编程语言建立企业级应用。 J2EE 技术的实例包括 Java Servlet、Java Server Page(JSP)和 Enterprise JavaBeans(EJB)。 在此应用服务器内运行的电子业务应用必须遵守这些规范。因此,应用可以在多种电子业务 平台和多种硬件环境之间移动,从而消除了厂商锁定。 管理控制台是一种图形控制台,用于部署、配置和精确调整可在容器中运行的应用。管 理控制台借助标准 Web 浏览器访问,可以从世界上任何地方远程管理部署,对于不总在现 场的系统管理员来讲,这个特性非常重要。 命令行工具属于任选工具,可帮助建立和部署应用,包括编译器、管理工具和部署工具。 硬核心开发人员可以利用这些工具节省时间和提高效率。命令行工具很重要,因为它能增强 开发人员的能力和提高生产率,当通过部署新应用提高竞争优势时,这些特性异常重要。 7.4.3.2 在容器内部 在应用服务器容器内部,应用主要有三个层,如图 4 所示。 表示层使用户能与系统交互。 业务层能封装业务规则和数据逻辑,并可重复用于各种类型的展示层。 后端层用于应用集成。 322 图 4:应用服务器的三个层 下面简要介绍应用服务器内的展示层和应用层的功能和使用情况。(后端层将在本文后 面的“应用集成”一节中详细介绍。) 7.4.3.3 表示层 表示层管理用户交互。J2EE 为建立动态 Web 页面提供两种技术:Servlets 和 Java Server Pages(JSP)。使用 Servlets 还是 JSP 或者两者一起使用,这取决于开发环境和开发人员。 Java Servlets 执行展示逻辑,如请求路由。Servlets 需要 Java 知识,因此必须具备开发 人员级水平。Java Servlets 与 CGI 程序或 ISAPI 扩展相似。 Java Server Pages(JSP)提供真正的展示视图。它们不需要 Java 知识,可由 Web 设计 者维护。JSP 可以通过定制的标记库扩展,使各机构能建立自己的动态 Web 页面系统。JSP 与 ASP 或 PHP 程序相似。 将 Servlets、JSP 和标记库组合使用后,可以实现与系统的任何瘦客户机接口。应用服 务器支持所有展示部件,包含的全面 Web 服务器可以在与应用服务器相同的流程中运行。 7.4.3.4 业务层 展示层可以看成是应用的外观或脸面,业务层则好比大脑。它包括系统的逻辑和处理功 能。在 J2EE 中,业务层可以涉及多台服务器,而且可以包含许多 Enterprise JavaBeans(EJB)。 323 BEA WebLogic Integration 的应用服务器功能同时支持 EJB 1.1 规范和较新的 EJB 2.0 规 范。EJB 2.0 中规定了三种主要的 Enterprise Beans: Session Beans(对话豆)是业务流程对象,如两个银行帐户之间的资金转移,执行购买 定单批准路由,或者计算定单价格等。 Entity Beans(实体豆)是数据对象,如银行帐户、购买定单、员工、公司和厂商。 Message-Driven Beans(消息驱动豆)是消息传送对象,如登录服务。 应用服务器同时支持这三种 Beans,并提供 EJB 规范之外的先进支持,如高级持久性服 务、性能优化和动态实时部署。 7.4.3.5 应用服务器功能在 BEA WebLogic Integration 中的主 要价值 除展示层和业务层支持外,应用服务器还为关键业务电子业务系统提供高级特性,如可 扩展性、可靠性、安全性和标准兼容性。这些特性对 BEA WebLogic Integration 内的所有其 它功能区都有好处,详细说明如下: 可扩展性。可扩展性的定义是:“如果在部署(如内存、处理器或机器)中线性添加资 源,那么,当保持相同的响应水平时,吞吐量是否会线性增加?”对于那些希望在未来用户 负载增加后仍然能保持服务水平的企业来讲,可扩展性非常必要。BEA WebLogic Server 是 BEA WebLogic Integration 内的应用服务器,专用于满足企业的可扩展性要求,它包含的高 级负载平衡特性能将请求动态路由到一组服务器。它无需牺牲响应等级完整性就能添加服务 器。它还包括池技术,因而能在给定的时间内减少所需线程、插座或内存的数量。 可靠性。应用服务器具有容错特性。如果发生了较大的问题,如电子业务应用、操作系 统、硬件或网络中出现故障,应用仍然可以正常运行。实现的方法是将一组服务器组成集群: 如果某台服务器出现故障,另一台服务器可以接管,因而不形成单故障点。这种方法能降低 系统级故障风险,从而避免丢失潜在业务、引起客户不满意或造成数据的不准确。当企业的 赢利与电子系统功能密切相关时,可靠性就至关重要。 安全性。应用服务器不但能防止非法访问者访问关键业务应用(认证),还能禁止权限 不足的用户执行操作(授权)。它不但能通过安全域与任何现有安全系统(如 LDAP)集成 在一起,还能同时在展示层和业务层包含安全性和防火墙互操作性。 支持今天和明天的最新标准。从进入应用服务器领域的那一天开始,BEA 就一直采用 标准并促进先进标准的制定。包含市场领先应用服务器的 BEA WebLogic E-Business Platform 率先支持开放标准,包括 Java、XML 和 Web Services。 324 7.4.3.6 应用服务器总结 借助其 BEA WebLogic Server,BEA 能提供世界上的头号 Web 和无线应用服务器,增 强世界领先公司的多数高级电子业务应用。作为 BEA WebLogic Integration 的核心组件,它 支持所有主要的 J2EE 技术,包括 JSP、Servlets 和新 Enterprise JavaBeans 2.0 标准。它不但 支持多种图形用户界面,如 Web 浏览器和无线 Web 设备、应用和小应用程序,还为电子业 务应用提供安全可靠的可扩展环境。 7.4.4 应用集成 为支持当今的业务需求,应用集成项目必须将 ERP、CRM 和遗留的大型主机等企业系 统连接在一起,不但要互相连接,还要与众多 Web 和无线应用连接。根据 Forrester Research 的报告,72%的公司都将集成看成是电子商务的关键,在被访者当中,有 62%的人购买了软 件工具,目的是将内部应用连接在一起。 虽然 ERP 和 CRM 等内部重点企业应用能为企业提供宝贵数据和服务,但只有新型 Web 和无线连接才能与全球的潜在客户、当前客户和供应商共享实时信息和服务。传统上,利用 资源密集型应用集成(EAI)项目将两个打包应用集成在一起不但需要专有技术,还需要长 期服务。当然,随着与现有系统连接的新 Web 应用的增加,这种复杂性还会大大提高。 7.4.4.1 应用集成问题 为深入了解应用集成背后的动力,请考虑图 5 所示的情况。 图 5:全方位集成情况 325 传统集成方法如图 5 所示,它通过硬线人工将系统连接在一起。目前,这些集成项目涉 及: 必须非常熟悉两种系统的细节 引入多种专有技术 将集成解决方案和技能重复用于其它应用的能力有限 人工开发集成连接,不但时间长,占用的资源也多。 应用适配器是一种软件,提供应用和集成服务器之间的接口。事实上,正如许多公司所 抱怨的那样,即使是现成的适配器也需要大量重映射和人工重编码才能满足集成要求。虽然 ERP、CRM 和 MRP 等系统能提供企业所需的许多功能,但通常都需要做些修改才能满足公 司的特殊要求。这种有限配置或系统的“vanilla”实施很少见,但这正是现成适配器的构造 方法。 虽然服务保证和全方位人工编码可以满足单个项目的要求,但修改计算环境(如升级到 目标应用或数据库)需要额外支持才能适应变化。 目前,从众多 EAI 厂商处可以购买到几种集成选项。但是,每家 EAI 厂商都提供自己 的解决方案(用于编写应用适配器)和其它 EAI 工作(消息转换、消息格式、消息翻译和 路由)。迄今为止,任何 EAI 厂商的市场份额都不高,也都无法使自己的技术成为集成标 准。事实上,市场非常分散,以致于打包应用厂商(如 i2、PeopleSoft、SAP 或 Siebel)没 有动力为自己的应用生成适配器。每家集成厂商都将继续推销用于构造适配器的专有 API, 这使适配器无法发展成一种集成技术,最终为最终客户造成了持续的集成隐患。 7.4.4.2 集成标准的兴起 那么,为什么没有事实上的标准平台呢?据 Forrester Research 调查,缺乏实现集成的方 式标准是主要的障碍: “转向电子商务使应用集成成为公司的关键业务。但是难以 处理遗留应用和家庭增长式集成解决方案的公司正陷入集成的泥 坑,直到标准形成和技术成熟时才能解脱出来。” 所幸的是,应用集成市场缺乏广泛采用标准的事实是由市场本身而不是一家厂商形成 的。正为未来铺路的重要标准有三种: J2EE Connector Architecture(J2EE CA)。J2EE Connector Architecture 是 Java 2 Enterprise Edition 的扩展,它对应用开发进行革新。J2EE CA 为所有应用的应用集成和适配 器开发提供了标准方法,包括 PeopleSoft、Siebel、SAP 或 CICS。J2EE CA 兼容适配器将在 支持 J2EE CA 标准的任何集成服务器中运行。J2EE CA 等标准的采用使打包应用厂商能构 326 筑可在任何 J2EE 兼容型应用服务器中工作的应用适配器。 Java Messaging Service(JMS)。正在简化集成的第二种标准是 Java Messaging Service (JMS)。JMS 提供与消息传输机制的标准编程接口,如 IBM MQSeries、Microsoft Message Queue 等。JMS 尤其重要,因为它通过标准方法将现有消息传送系统集成到现代电子业务应 用中,最终增强 Web 型企业的实力。 Web Services。Web Services 将 XML 作为数据格式,将标准 HTTP 协议作为传输协议, 以此方式将现有应用集成到企业中。与其它方法(如 CORBA 或消息传送)相比,这种方法 的侵入性不强,因而是与现有系统(如用 C 或 COBOL 写成的应用)集成的最佳方法。BEA 是采用和支持 Web Services 的业界领先厂商,它为 Web Services 提供综合平台。(我们将在 本文后面的“B2B 集成”一节中进一步介绍 Web Services 支持。) 由于 BEA 以及其它业界巨头拥护这些集成标准,因此业界出现了来自电子业务平台厂 商和 ISV 的大量买入。Java Messaging Service 和 J2EE Connector Architecture 更是推动了集 成适配器市场的发展,它们可以下载或立即购买。如果适配器不存在,可以自己编写适配器。 或委托第三方编写。有一种公认的通用 J2EE 应用服务器总线,可以使适配器只需编写一次, 而无需编写若干次。这使得应用集成更简单,可管理性更好,如图 6 所示。 327 图 6:借助应用服务器总线集成,不但能简化应用集成过程, 还能将新应用快速集成到基于标准的通用框架中。 7.4.4.3 应用集成体系结构 BEA 认为应用集成对客户至关重要,随着 J2EE CA 的普及,BEA WebLogic Integration 能够提供功能丰富的应用集成平台。最重要的是,BEA WebLogic Integration 支持前面提到 的所有标准,包括 J2EE CA、JMS 和 Web Services。BEA 的承诺是提供便携式开放标准, 并将不断创新,将这些特性推广到未来的 J2EE 标准中。 从体系结构上看,BEA WebLogic Integration 是完整的应用集成平台,由两个组件组成: Integration Framework 和 Adapter Development Kit。Integration Framework 为商业用户容易、 顺利地设计集成式解决方案提供集成式环境。Adapter Development Kit(ADK)则有利于按 照 J2EE Connector Architecture(可运行在任何 J2EE 兼容型应用服务器上)快速开发应用适 配器。这两个组件结合起来,能够为应用集成提供简单、系统、基于标准的方法。 7.4.4.4 集成框架 应用集成中最困难的问题是弥补业务分析家和开发人员之间的缺口。业务分析家在各种 企业信息系统方面经验丰富,开发人员则擅长服务器方 Java 编程。这两者必须一起工作才 能解决业务问题。随着系统的发展,业务分析家必须能独立获取和调试应用之间传递的业务 数据。迄今为止,这个目标尚未实现。带有 Integration Framework 的 BEA WebLogic Integration 将通过全新方法解决这个问题,使业务分析家能参与集成过程,使 IT 人员无需再借助传统 的专有解决方案进行人工编程。 Integration Framework 允许构筑现有系统的应用视图。应用视图背后的观点是,开发人 员应首先对电子业务系统和现有系统之间的实际适配器集成进行编码。这样,业务分析家就 可以调用这个适配器,方法是通过应用视图发送和接收 XML。这个应用视图是从业务分析 家提取技术集成细节的接口,使之能集中精力解决手头的业务问题。例如,业务分析家无需 了解结构化查询语言(SQL)就能在数据库中生成记录,或者无需深入了解 BAPI 或 IDoc 接口就能从 SAP 请求信息。借助这个功能,业务分析家无需依赖技术人员的支持就能使用 现有系统,如图 7 所示。 328 图 7:应用视图 借助应用视图,现在可以将现有企业信息系统作为商业服务,即接受 XML 数据作为输 入,返回 XML 数据作为输出。这使得用户可以按同样的方式对待现有系统。集成 SAP 与集 成 CICS 的唯一基本差别是 XML 的内容,因而甚至可以知道哪个现有系统正被调用。现在 还可以将业务分析家纳入应用集成。 应用视图还有助于快速构筑涉及现有系统的宝贵子流程。例如,SAP 系统可以通过应 用视图暴露服务,进而更新客户信息。当事件在 Siebel 等另一系统中产生时,SAP 系统无 需编写任何定制代码连接就能调用这些系统。由于业务流程管理机制(后面将详细讨论)拥 有基于 XML 的工作流功能,因此这个功能是可以实现的。这种方法的优点是能够快速开发 应用,这一特性在业界尚未听说。 7.4.4.5 适配器开发工具(ADK) BEA WebLogic Integration 提供的适配器开发工具(ADK)能简化资源适配器的开发、 测试、打包和分布。使用 ADK 的公司将得益于以下功能: 根据特殊 EIS 集成需求可视定制现成适配器 辅助开发 J2EE CA 适配器和 JMS 适配情况 记录设施 打包设施 内含 DBMS 适配器和电子邮件适配器,带全部源代码 通过提供集成平台和适配器开发工具,BEA 培育的市场不但能为 ISV 和系统集成商建 立适配器提供赢利机会,更重要的,还能为客户提供灵活性,并为寻求基于标准的集成解决 方案的公司缩短上市时间。ADK 能够使以下人员的工作更轻松: 客户将受益于许多合作伙伴提供的大量适配器。 应用开发人员不但可以使用 ADK 为专用系统建立适配器,还可以在建立电子业务部署 时定制现成适配器。 专业集成商可以使用 ADK 帮助客户开发集成解决方案。 SAP、Siebel 和 PeopleSoft 等应用厂商可以使用 ADK 提供适配器,使 J2EE 环境中的客 户能快速从部署产品过程中增值。 采用这种基于标准的方法实现应用集成的客户不但能得益于 BEA 及其大量合作伙伴所 推动的快速市场采用,还可以从大量适配器中作出灵活的选择。欲知可用适配器的最新信息, 请与 BEA 销售代表联系。 7.4.4.6 应用集成的其它价值 除 Integration Framework 和 Adapter Development Kit 提供的前述优点外,当执行应用集 成时,还可借助 BEA WebLogic Integration 获得以下好处: 完整的集成解决方案。与应用集成以及从应用接收事件的过程通常是大型跨企业业务流 329 程的一部分。实现的基础是与 BEA WebLogic Integration 其它功能区的紧密集成和互操作性。 应用服务器使用户能利用“面向集成”方法,快速开发和部署能满足企业级需求的可扩展、 安全的新应用。业务流程管理功能区使公司能集成决策人以外的涉及多种企业信息系统的应 用。最后,B2B 集成功能区能提供关键的“最后一哩”集成,以便实现流程的自动化,并 与业务合作伙伴的共享流程集成在一起。 受益于基于 XML 的通用协议。将大量应用集成在一起时,一般需要翻译两种或多种语 言。BEA WebLogic Integration 解决这个问题的方法是提供基于 XML 的消息传送协议。通用 协议使应用集成更为可行,因为每个应用只需要与通用协议集成,而不需要将应用相互集成。 借助通用协议,所有应用都借助相同的语言 XML(构筑商业数据的事实标准)交流。作为 BEA WebLogic Integration 的主要特性,这种通用协议能大大简化应用集成。 执行双向集成。BEA WebLogic Integration 可以通过 J2EE Connector Architecture 调用现 有应用,现有应用也可以将事件发送到 BEA WebLogic Integration。这意味着通信是双向而 非单向的。感兴趣的各方可以订阅产生的事件,BEA WebLogic Integration 则负责管理订阅 和路由过程。例如,当 CRM 系统中生成新客户(如 Siebel)时,可以触发 BEA WebLogic Integration 中的某个事件,启动业务流程,如在 SAP R/3 中枢如新客户数据然后发送“欢迎” 电子邮件。 在两个系统之间容易地转换数据。执行集成时,两个系统间的数据映射是必要的。借助 XML 型页面语言转换(XSLT),可以容易地在应用之间转换 XML 数据,XSLT 是将 XML 文档从一种形式转换为另一种形式的标准。这样能进一步简化应用集成过程。 事务处理功能。重要的业务流程的事务处理可能会横跨多个系统。BEA WebLogic Integration 可以协调多种电子业务应用间的事务处理以及支持业界标准 XA 协议的一个活多 个现有系统,从而实现真正的互操作性。事务处理协调逻辑内置在 BEA WebLogic Integration 中,编写资源适配器中可节省大量工作。 安全性。BEA WebLogic Integration 利用 J2EE CA 规范的安全特性,包括应用服务器和 企业信息系统之间的交互管理。这使得应用服务器能同时管理安全合同以及到目标应用的登 录,方法是比较应用服务器中的身份与目标应用中的身份,从而简化安全和认证过程。 可扩展性。BEA WebLogic Integration 通过连接池重复使用与外部系统的连接,以便提 高可扩展性,使许多客户机只借助少量网络连接就能使用现有系统。 7.4.4.7 应用集成总结 应用集成是当今许多企业面临的问题,尤其是怎样通过电子业务实现利润和节约成本的 问题。现有应用集成技术因缺乏标准平台而无法满足业务的需求。BEA 视图通过 J2EE Connector Architecture 等标准改变应用集成市场,为客户提供开放集成技术。 BEA WebLogic Integration 的应用集成功能以这些标准为基础,为将应用集成到现代电 子业务系统中提供强大、灵活、可扩展的平台。主要优点包括增值工具,用于快速集成的适 330 配器开发工具,与 BEA WebLogic Integration 平台其它功能区的互操作性,能借助集成框架 以应用视图形式表示现有系统,以及更好地支持业务分析家。 7.4.5 业务流程管理 为了解 BEA WebLogic Integration 中的业务流程管理功能区,必须了解电子业务流程或 “工作流”。电子业务可以相当简单,只包含两个部门 IT 系统之间的请求/响应;也可以非 常复杂,涉及到许多电子系统和人员,需要许多天甚至几年才能完成。据 Gartner 统计,这 些流程的影响是巨大的,它们能显著提高效率: “从自助模型到 B2B 事务处理洽谈,工作流可以成为为电子业务应用和用户提供以流 程为中心、对状态敏感的控制服务的基本机制。工作流使电子业务能补充(某些情况下甚至 可以消除)对人员的依赖。工作流的特点是,可重复、可控制的精确流程可以与数据驱动的 用户定制经验结合起来。”1 假定有这样一个电子业务流程。客户从网上商务站点订购了一件产品,接到货物后又想 退货,因此开始执行以下流程: 由人使用电子系统记录客户已收到货物; 电子系统安排对货物的人工审计; 由人打开包装,检查内容,并电子记录; 电子系统检查关于退货的政策,确定是否接纳客户的退货(可能要在此过程检查用户的 历史,包括欺诈探测系统); 如果拒绝退货,将启动另一业务流程,把包裹退换客户,并附上一封信,解释拒绝退货 的原因; 如果接受退货,将启动另一业务流程,处理与退货相关的客户信用问题,并将货物退还 到原始制造商。 业务流程设计技术并不是个新概念。多年来,企业已经从设计这种流程中获得了很多好 处,包括: 完全实用的业务流程,能提高生产率 实现系统的自动化,提高效率 消除许多人工错误 降低工作量,缩减成本,增加赢利 7.4.5.1 怎样设计电子业务流程? 以前,开发人员借助使用事件和序列或者大型主机批处理的定制工作流产品设计业务流 程。事件和序列不容易实现互操作,也不容易利用应用服务器中的基础设施和技术。批处理 也不理想,因为系统不能实时执行。 最近,使用 J2EE 的客户建成了全方位 EJB 或 JSP 组件,它们在应用服务器内运行。这 里的问题是,每个业务流程都通过硬编码进入应用(可以要使用大量“if”语句)。 331 这种人工方法会形成难于维护和了解的复杂业务流程,而且需要大量 IT 支持。一般情 况下,这些业务流程无法重复利用,不但增加了成本,还降低了机构实现业务目标的速度。 设计业务流程只由开发人员参与,不允许业务分析家调整业务流程,因此竞争力不匹配。最 后,只有很少高级业务流程特性,如专业监控功能、发现问题以及指出机构流程低效率之处 等。 一种较好的方法是利用基本业务流程机制。Giga Information Group 说道:“总之,用工 作流取代进入应用的编码业务逻辑后,公司的开发/集成过程可以加快 50%~150%。”2 除初始部署和集成过程中能节省大量时间外,Giga 还预测到,经过一段时间,流程集 成和工作流技术实现的连续优化和修订将大大节省资金。“修改流程后,可以获得这种幅度 的改进,因为修改业务流程将更加容易,它只需替代模型,而无需修改应用代码。”3 例如,在信用授权业务流程中,数分钟之内就可以将预授权信用限制从$100 增加到 $300。这就是说,到目前为止,应用内的“全方位”修改已发生了巨大的变化。 业务流程管理技术可以提供宝贵的性能数据,使各机构能监控现有流程,发现问题,评 估机构性能,并改善业务流程的流动。应用这些技术可以向管理员实时提供机构内由系统和 人力执行的工作的准确数据。借助这些信息,可以将任务分担到其它资源,以便消除瓶颈和 停机。如果效率仍然提不高,管理员可以评估性能数据并对流程进行修订。 在电子业务部署中使用业务流程管理功能的方式有两种: 编写自己的业务流程管理机制。开发人员可以从头开始编写业务流程软件,例如借助 BEA WebLogic Server 产品编写 J2EE 工作流应用。 这种方式的灵活性高,因为用户可以全面控制系统。但是,这种解决方案并不太理想, 因为开发这种解决方案太昂贵,速度慢,不但延长了上市时间,还增加了成本。虽然开发人 员的水平可能很高,但很难做到与专业产品一样功能丰富和没有错误。遗憾的是,定制解决 方案还不如相应的现成产品,因为没有专业机构的支持,以后也不能对软件进行升级。 购买不基于应用服务器的流程机制产品。市场上有大量“点”流程技术产品。某些情况 下,在电子业务部署中使用这种产品比较可行,将也有许多明显的缺点。第一,需要花大力 气维护厂商关系。其次,解决方案不基于基本电子业务平台,因此不能获得基本平台服务的 好处。最后,它可能无法与电子业务应用、现有系统和业务合作伙伴互操作。最后的结论是, “点”解决方案只适用于解决点问题。但是,当下一个项目需要一年前——甚至几个月前— —无法预测的功能时,只使用点解决方案是无法适应的。 7.4.5.2 BEA WebLogic Integration 的业务流程管理功能区 BEA WebLogic Integration 内的业务流程管理功能区(见图 8)属于单一体系结构的解 决方案,用于开发、实施和监控跨越多个应用、多种技术(如 PDA 和传真机)和多名人员 的企业级复杂电子业务流程。借助屡获大奖的流程技术(2001 年 Crossroads A-List 奖的得 332 主),这种强有力的流程机制能为 BEA WebLogic Integration 解决方案提供许多创新特性。 它支持插入式体系结构,使系统能无缝集成并充分利用为应用服务器编写的应用以及借助应 用集成功能区集成在一起的现有系统的强大计算功能。最后,流程机制还能增强 B2B 集成 功能区所需的共享和专用业务流程。 图 8:BEA WebLogic Integration 的业务流程管理功能。 对电子业务来讲,了解和主动管理业务流程都是必需的。业务流程管理能实现业务流程 的标准化和流畅化,因而能帮助企业获得竞争优势。这种强有力的流程机制能为基于系统/ 应用的业务流程和基于人工的传统工作流提供有效的端到端管理。作为开发环境,业务流程 管理不但能借助 EJB 组件快速安装和部署 Java 应用,还能进行高级业务元素的工作流装配, 如应用视图、协作流程及其它服务。 7.4.5.3 业务流程管理体系结构 BEA WebLogic Integration 的流程模型如图 9 所示。其业务流程管理功能包括: 设计业务流程。业务分析家只需在屏幕上拖放元素就能完成流程的设计。流程设计使用 熟悉的流程图。设计元素(指节点)代表端到端业务流程的各种元素,包括“开始”、“任 务”、“事件”、“决策”、“加入”和“执行完毕”等。这样有利于快速脱机流程开发和 333 后续优化。 执行业务流程。基本业务流程机制负责管理流程在操作环境中的执行,自动排序和执行 预定流程元素,并借助 XML 表示数据,用 JMS 传送信息。对于以应用为中心的业务视图, 流程行为可能会有很大的变化。此机制还可以在业务流程中涉及到人,将工作分配给用户或 职位。工人可以根据当前的任务清单工作,经理也可以查看任务清单,以便管理并在必要的 时候调换任务。 监控和优化业务流程。使用户能跟踪流程状态,实时查看流程,并收集统计数据形成报 告。接下来,用户还可以根据这些数据评估流程,提高性能和吞吐量,并增加开机时间。无 需中断业务流程就可能进行必要的修改。 图 9:业务流程管理功能区的流程建模 7.4.5.4 业务流程管理的主要价值 业务流程管理功能区具有几个优势,能保证提供可扩展的解决方案,满足机构当前和未 来的需求,这几个优势包括: 流程封装。使用户能将业务流程逻辑封装在一起,并从流程机制独立管理。这种封装提 供电子业务需要的灵活性和可操作性。通过隔离这些元素,用户无需影响整个流程或编写另 外代码就能快速修改流程。最后,流程封装还有利于快速开发和部署组件应用或业务流程, 进而大大节约成本,缩短上市时间。 包含业务分析家。也许 BEA WebLoigc Integration 业务流程管理功能区中最重要的优点 是能够将流程逻辑与应用组件分离开来。开发人员首先对低层业务流程组件编程,并允许业 334 务分析家利用这些流程,即借助直观的图形用户界面设计端到端业务流程。业务分析家可以 查看关键数据,而且在几分钟之内就能修改业务流程。这种功能使 IT 人员能集中精力处理 战略价值更高的问题,而不只是实施全方位修订。 可重复利用。使业务分析家能设计业务流程元素,方法是利用 BEA 提供的现成元素进 入 IT 人员编写的 Java 或 EJB 组件内部,,或者设计高级业务服务。遗留系统可以集成到流 程中,甚至还可以设计用于整个业务流程的模板。令人兴奋的是,一旦定义了这些核心业务 流程元素,就可以重复利用它们,建立更大、更复杂的业务流程。 动态业务流程。在生产环境中,流程管理机制能主动执行和管理工作流应用。通过联机 监控、动态重配置和统计报告功能,还可以进行连续改进和精确调整。 混合行为。业务流程行为可能是直接方法调用和消息的混合。流程机制负责处理这些行 为流程的状态。 基于标准。BEA WebLogic Integration 使用 J2EE 兼容型技术,包括 Java 基础、JSP 和 EJB 互操作性、用于流程元素间数据传送的 XML 以及用于业务流程组件间消息传送的 JMS。 这些开放标准意味着在 IT 人员的技能适用于不同的项目,而且 IT 人员可以协同完成同一项 目的不同部分。因此,使用标准技术(XML)和开放编程 API 意味着解决方案可以扩展, 为未来发展留有余地。 7.4.5.5 业务流程管理总结 总之,对于那些希望业务流程能与新电子业务计划互操作的机构来讲,BEA WebLogic Integration 内屡获大奖的业务流程管理功能区是非常理想的选择。借助应用服务器、应用集 成和 B2B 集成功能区的功能,BEA WebLogic Integration 能提供完美集成在一起的端到端电 子业务解决方案,使业务专家和 IT 专家能发挥各自的核心竞争力,实现优势互补。IT 人员 和业务分析家可以积极协作,开发、管理和优化 B2C 和 B2B 计划,缩短上市时间,提高赢 利能力。 7.4.6 B2B 集成 所有企业级机构,甚至那些宣称自己不参与“企业到企业”的机构,也必须与其它企业 交互。虽然目前 B2B 的重点主要在供应链和采购上,但有所突破的企业一定可以受益非浅。 除供应链和战略采购活动外,B2B 还可以扩展到需求链参与者(如分布商、代理和零售商) 和业务合作伙伴(如银行、保险服务、医疗提供商和后勤提供商)。某些情况下,甚至可以 包括公司内的分立系统,如与最近并购的公司或原先海外业务部的流程和系统集成在一起。 无论怎样部署,B2B 集成的复杂性都会随业务合作伙伴的增加而提高。 传统的 B2B 集成技术能增强企业的交流能力,如通过增值网进行的电子数据交换 (EDI)。但是,EDI 也有很多缺点。随机许多机构都采用了 EDI,但多数机构都不打算完 335 全依赖它。纯 EDI 解决方案的主要缺点包括: 业务之间不能实时动态交流。信息是成批发送的。它不属于实时解决方案,因为信息信 息是作为点到点消息而非业务对话的形式发送的。 对话不能调解。传统解决方案是业务合作伙伴之间的全方位点到点集成。基础设施不允 许中间人提高服务质量,如路由、过滤和转换。添加新业务合作伙伴不容易,因为没有多个 合作伙伴订阅对话的概念。 实施慢,难以维护。传统解决方案一般需要 9-12 个月的实施时间,因而延长了上市时 间。它们还难于定制和维护,因为数据是严格地一步一步组合成流程的,不仅如此,企业还 必须熟悉神秘的 EDI 词汇。当企业希望改变 B2B 对话途径时,必须对 EDI 的僵硬性付出机 会成本。 昂贵。通过增值网运行的事务处理的建立和维护成本较高。单是增值网费一项,中型企 业每年就要支付$25,000~$50,000。但是,传统 B2B 解决方案的开发和维护周期长,不仅不 利于应用开发,本身也十分昂贵。 7.4.6.1 将 Internet 作为 B2B 媒介 由于使用遗留技术和网络的实际成本和机会成本不断增加,各公司都将 IT 资源投入基 于 Internet 的系统中,以便实现财务和战略目标。Ecomonist 在最近的一份报告中指出了支 持新型电子业务模式所必需的业务: “ternet 广泛的连接性使公司能与合作伙伴和客户建立三角形“信息关系”,将他们作 为协作者,这些协作者能够与公司一起寻找提高整个供应链和需求链效率的途径,并共享由 此带来的好处。采用基于 Web 技术的新兴技术并在交互式更强的商业环境中将它们与“遗 留”IT 系统连接起来并不容易,任何企业都不再是独立的实体,这个观念一定要转变过来。 大公司的目标应该是成为小公司的电子业务集线器,保证他们具有说服力。涉及的公司必须 愿意将供应商和客户纳入其业务流程,并同样了解业务合作伙伴的流程。” 新 B2B 解决方案能利用 Internet 以及 Java 和 XML 等技术,以便消除各种贸易合作伙伴 的入门障碍,缩短部署周期和降低成本,妥善管理各公司的实力,并实现合作伙伴之间的实 时通信。世界上的许多大公司都将继续使用 EDI 等传统解决方案,因为它们仍有生命力, 基于 Internet 的新电子业务平台必须与这些遗留系统共存。 7.4.6.2 BEA WebLogic Integration 的 B2B 集成功能区 随着 WebLogic Integration 中 B2B 集成功能区的出现,BEA 能够为新 B2B 功能提供新 一代基础设施,这些 B2B 功能在 B2B Internet 报告中称为协作商务。如果说传统 B2B 集成 好象用步话机与业务合作伙伴通信,那么协作商务就好象是买者和卖者之间的交互式受控 “电话会议”。贸易合作伙伴之间的实时对话使他们能主动洽谈并执行商业事务处理,而不 只是传送信息。无论这些“商业事务处理”需要多长时间,会涉及到内部或外部的多少业务 方或 IT 系统,B2B 集成功能区提供的基础设施都能帮助各公司妥善管理每种 B2B 行为, 将这些行为作为无缝的集成式安全业务事件。 336 7.4.6.3 Web Services Web Services 是 B2B 集成功能区最核心的部分。Web Service 属于电子业务应用,能借 助 SOAP、UDDI 和 WSDL 等业界标准技术将公司引入 Internet。Web Services 无疑是 B2B 集成的未来,原因是: 有效。它使用 Internet,因而要比增值网便宜得多。 与防火墙配合。Web Services 使用 HTTP,所有防火墙都允许通过,由于无需打开防火 墙端口,因而不会带来安全风险。 用 XML 表示数据。XML 是可扩展的企业标记语言,可用于组织企业数据,已得到大 家的公认。XML 简单,不会将企业锁定到任何特殊方法。 大家拥护它。Microsoft、Sun、BEA 和 Oracle 等大电子业务厂商从未象现在这样一致拥 护一套技术。为保证未来的成功,与电子业务相关的这些厂商都拥护 Web Services。 BEA 积极推进 Web Services 标准的发展,除 BEA WebLogic Integration(包括 BEA WebLogic Server)提供的 Web Services 功能的扩展集合外,BEA 还在 BEA WebLogic Server 中以独立产品的形式提供 Web Services 技术。 BEA WebLogic Server 支持主要 Web Services 标准:SOAP、UDDI 和 WSDL。它包括公 布和订阅 Web Services 所需的功能,甚至还能与 EJB 业务层实现互操作,从而无需另行编 写代码就能将 Web Services 与电子业务部署的其余部分连接起来。BEA 认为这种 Web Services 非常适用于简单 Web Services——提供支持基础 Web Services 计划所需的核心功能。 虽然这些简单 Web Services 对某些业务流程有用,但 BEA 认为简单 Web Services 不适 合常用的或提供真正业务价值的企业 Web。为满足这种需求,BEA 率先推出了 Business Web Service。Business Web Service 可与使用多种协议和对话模型(RosettaNet 1.1 和 2.0、cXML、 XOCP、基于文件的传输、对等协议、集线器和语音等)。这时必须有业务关系和协议的定 义,以便路由和过滤消息,并能够执行、管理、监控和经营安全、复杂的对话。除业务流程 管理和应用集成功能外,BEA WebLogic Integration 的 B2B 集成功能区也能提供高级 Web Services 支持,显著增强 WebLogic Server 核心支持的简单 Web Services。 对 Simple Web Services 和 Business Web Services 的支持比较如表 1 所示。表中说明了 BEA WebLogic Server 提供的核心 Web Services 支持,以及由 BEA WebLogic Integration 提 供的对此支持的大量附加物。 BEA WebLogic Server BEA WebLogic Integration Web Services 支持 Simple Web Services Business Web Services 标准 SOAP、UDDI、WSDL XOCP 、 RosettaNet 、 cXML、HTTP、SSL 特性 点到点 RPC 和消息传送 非事务处理型 多方 协作和工作流 事务处理型 337 Web 安全: 认证 授权 高级安全性: 无争议 数字签名 对话 简单 对话状态 个性化 简单 基于协议 表 1 Simple Web Services 和 Business Web Services 的 Web 服务比较 7.4.6.4 B2B 集成体系结构 B2B 集成的主要体系结构组件如下: BEA WebLogic Integration 及其 B2B 集成功能区支持并实现了协作商业计划,使业务合 作伙伴能生成、路由和管理贸易环境中的消息。BEA WebLogic Integration 能交易贸易合作 伙伴之间的 XML 消息。以下服务质量能加速和增强“渠道主人”(促进供应链或需求链形 成的公司)与参与公司(可以包括供应商、合同制造商、分布商、代理以及后勤或金融服务 提供商)之间的 B2B 集成: 不依赖于传输协议,目前支持 HTTP/HTTPS 对话定义,包括流程和词汇定义 可以为消息定义服务质量(如有保证的供应) 调解的消息传送模型,同时支持发送和接收过滤器 支持用户定义的消息路由和过滤 能灵活地应用消息或数据内容转换。例如,可以将二进制数据转换成 XML,反过来也 一样 支持多种合作伙伴需求的多种配置选项。BEA WebLogic Integration 为 B2B 集成支持多 种配置。多个选项有助于最容易地支持大量业务合作伙伴,或者通过紧密集成支持战略合作 伙伴之间的实时连接要求。部署情况由所用的业务协议和公司及其业务合作伙伴的集成要求 确定。 第一种配置特性是将 BEA WebLogic Integration 作为“集线器”,即允许在“对话”处 实现集线器与参与公司之间的调解消息交换。BEA WebLogic Integration 还可以部署在业务 合作伙伴站点,这是平台的另一种配置。如果配置为“对话”,BEA WebLogic Integration 就成为机构内部专用流程与外部公共流程之间的接口,并能够与其贸易合作伙伴共享。这种 部署配置带有集线器和对话模型,是使用 BEA 的可扩展开放协作协议(XOCP)时的典型 情况,XOCP 能为特定对话确定为信息(词汇)和业务协议(流程)。对话和业务流程开始、 执行和完成后,对话管理功能将跟踪和管理这些长时间对话,保证它们顺利完成,并协调业 务流程的整个执行过程。 BEA WebLogic Integration 还支持对等配置,这种配置在使用 RosettaNet 等业务协议时 更加典型。支持 RosettaNet 1.1 和 2.0 使各公司能顺利部署 BEA WebLogic Integration,除借 助 BEA WebLogic Integration 与其它公司连接外,还能与第三方的 RosettaNet 兼容型解决方 338 案交互。 BEA WebLogic Integration 的业务流程建模功能可用于图形模拟和执行机构间业务流 程。编程接口也可以实现。 作为低成本方案,小贸易合作伙伴可以通过 BEA WebLogic Integration 支持浏览器访问 的特性接入贸易网络,方法是使用解决方案的文件共享功能。 以流程为中心的 B2B 集成方法。BEA WebLogic Integration 使渠道主人及其业务合作伙 伴能容易地模拟、执行和管理机构间的业务流程。BEA WebLogic Integration 使业务分析家 能设计协作性业务流程,并与其它内部流程和系统集成在一起。运行时,流程机制能管理预 定业务流程的执行。监控功能使各公司无需中断正常流程就能快速发现瓶颈和优化流程。 为保护公司间交互过程中产生的专有信息,协作专用流程应独立存在。协作定义和管理 的共享流程作为本地流程部署,只在每个贸易合作伙伴处执行,以保证专有信息的安全性。 在这种方法中,流程取代了专有或硬编码系统交互。流程与基本技术相独立有助于提高 灵活性,保证信息安全性,无需作资源密集型修改和调整,并能降低总拥有成本。 基于 Web 的动态管理控制台。管理员可以为企业 Web 远程控制多个参数。可以选择的 管理功能包括管理贸易合作伙伴(添加或删除贸易合作伙伴、授予和撤消对话访问权等)、 配置消息传送服务、监控目前对话、浏览系统状态(交互、消息供应和记录)、定义安全特 性(私有、认证、授权、无争议)和产生行为报告。 7.4.6.5 B2B 集成的主要价值 B2B 集成功能区能为企业提供非凡的价值,使企业不但能在紧密集成的对等环境中与 主要贸易合作伙伴连接,还能形成广泛分布但紧密互连的电子业务“能力网”,其价值包括: 管理主要 B2B 交互。B2B 集成的中间功能可以向 B2B 对话提供高级服务质量,包括消 息路由(将消息发送到相应各方)、消息转换(转换信息,以便阅读)和消息过滤(只收听 感兴趣的信息)。这种功能使复杂业务合作伙伴 Web 的管理更加容易——只需通过订阅或 不订阅操作就能在 Web 中添加或删除业务合作伙伴。 快速适应变化。用户可以动态添加或修改业务合作伙伴,快速模拟和管理合作伙伴关系。 动态业务流程可以通过与业务流程管理功能区的集成快速建立。现有内部系统可以参与动态 B2B 集成,利用应用集成提供关键的“最后一哩”连接。这样能够将每种协作商务行为作 为无缝的集成式安全业务事件对待。 快速、有效的 B2B 集成。每个机构都有自己的特点,在机构网中,不同的业务合作伙 伴可能希望使用不同的协议。B2B 集成功能区在内部支持主要协议(如基于文件的交换、 SOAP、cXML、ebXML 和 RosettaNet),因而开发人员无需花时间再学习它们和执行全方 位集成。这种协议有助于快速开发应用,缩短上市时间,降低开发成本和减少繁忙的工作。 339 它还为新贸易合作伙伴低成本进入此行业打开了大门。 快速开发 B2B 门户,以 Web 方式参与业务流程。B2B 集成功能区以 JSP 标记库和排序 技术的方式将一组工具捆绑在一起,用于建立基于 Web 的门户。对于不想实施高级 B2B 系 统的小业务合作伙伴或者没有现代 B2B 应用的业务合作伙伴而言,无需编写许多代码就能 以 Web 方式实现业务流程。业务合作伙伴可以登录到 Web 站点,可视执行业务流程操作。 内部部门也能如此操作。 与公司防火墙良好配置。对于那些能控制其企业 Web 协议的企业来讲,可以选择基于 HTTP 的协议,因而无需打开防火墙端口和暴露安全隐患就能将两个企业集成在一起。 容易地集成混合业务系统。B2B 集成支持多数主要协议,并允许建立定制协议,这意 味着无论使用哪种编程语言、中件、操作系统或硬件,新电子业务系统都能容易地与其它 Internet 型系统互操作。合并和并购集成、跨部门互操作性以及 B2B 互操作性等问题可大大 减少。 为未来的 Web Services 做好准备。B2B 集成支持未来的 B2B 集成——Web Services。 它包含主要 Web Services 技术,如 SOAP、UDDI 和 WSDL。对于打算拥护 Web Services 的机构来讲,不但可以立即将电子业务应用公布为 Web Service,还可以订阅业务合作伙伴 Web Services,并生成更先进的 Business Web Services。 从基本应用服务器核心受益。B2B 集成利用 WebLogic Server 核心获得明显的安全性、 可扩展性和可靠性。 使用业界标准技术。B2B 集成基于 Java、J2EE 和 XML,使开发人员只需学习一种技能 就能掌握整个业务集成,提高知识的效率,降低学习成本,增加赢利。 7.4.6.6 B2B 集成总结 总之,BEA WebLogic Integration 的 B2B 集成功能区能大大减小 B2B 参与和成功的入 门障碍。B2B 集成有助于为未来 Web Services 做好准备,因为它既能设计简单的 Web Services,也能设计更复杂的 Business Web Services。它开放,基于标准,能与其它 BEA WebLogic Integration 功能区互操作,能帮助用户实现全面的业务集成。通过利用 B2B 集成, 贸易合作伙伴组织可以发展成 Business Web Services 的低成本动态网。 7.4.7 结论 在本章节,我们讨论了 BEA WebLogic Integration 的用法、特性和优点,这种平台可用 于开发和部署电子业务应用,设计和执行电子业务流程,集成应用,以及执行 B2B 协作。 7.4.7.1 集成的商业价值 随着电子业务以及新型 Web 和无线应用的爆炸式增长,新型电子业务应用必须与原有 的企业信息系统结合起来,现代企业才能成功。业务分析家和 IT 人员必须紧密协作,这样 340 才能开发出新应用,为客户提供新产品和服务。只有综合分析客户信息以及战略业务合作伙 伴提供的需求链和供应链信息,营销活动才能成功。过去,许多集成计划都被看成为是 IT 问题。目前,企业越来越依赖多种技术满足业务需求和开展新的业务活动,这使得集成问题 越来越重要,这个问题不但涉及开发人员、建筑师和 IT 管理人员,还涉及到高层管理人员。 7.4.7.2 标准的重要性 迄今为止,某些标准尚未成熟,因而迫使许多 IT 机构采用点厂商提供的专有技术。单 个应用服务器、EAI、流 程 和 B2B 解决方案厂商已经将其技术融入企业体系结构——某些情 况下,需要将集成厂商集成在一起才能完成工作。今天,J2EE 的广泛采用,J2EE Connector Architecture 的推出,以及 RosettaNet 和 cXML 等 B2B 协议的大量涌现,相当于为统一添加 了双重催化剂。 7.4.7.3 可扩展的平台 这是一个平台游戏——只有提供基于标准的平台的厂商才能满足企业的未来需求。BEA WebLogic Integration 宣告了应用服务器和集成服务器合并的时代已经到来,因为它提供功 能全面的可扩展平台。它不但能为 IT 提供基于标准的合并解决方案,满足多种需求,还能 形成内在集成的方法,不但能增加投资回报,更重要的是,还能为企业提供未来投资保护。 借助应用服务器快速建立基于标准的新型电子业务解决方案。为企业级应用提供所需的 可扩展性、安全性和可靠性,保护当前和未来的技术和人力投资。 借助 J2EE Connector Architecture 在企业内集成多种多种新系统和现有系统。增强业务 分析家的能力,降低集成计划的短期和长期成本,并增加现有系统的商业价值。 理顺涉及决策人和电子系统的跨企业的复杂业务流程。提高企业效率,减小对 IT 人员 的依赖,使企业能够将运作与强大、灵活的流程组合在一起,并随着业务需求的变化而发展。 利用 Internet 快速加强与业务合作伙伴的关系,包括需求链上的地区分布商、供应链上 的战略参与者,以及能为企业提供增值服务的任何其它公司。企业可以扩展到包含最理想业 务合作伙伴提供的高价值服务和产品,许多新的商业机会将涌现,企业间交流的效率将提高。 为 Web Services 的未来做好准备,Web Services 是 Internet 出现以来最普及的计算标准, 使公司能快速通过 Internet 扩展业务,向全世界的所有大小公司提供服务、产品、信息和分 布式计算的好处。 如果您希望更多地了解 BEA WebLogic Integration,包括它能为您的企业带来哪些好处, 怎样简化最新的 IT 计划,怎样为企业提供未来保证,以及怎样利用它产生新的收入机会等, 请与本地的 BEA 代表联系。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档

相关文档