在本文中,您将学习如何利用 Java 2 Platform, Enterprise Edition (J2EE) 设计和开发 面向服务的体系结构(SOA)框架。通过采用 SOA 框架,企业可以最大程度地减少系统间的耦合,从而提高可重用性。本文从一个较高的层面概述了在 SOA 框架上进行的几次迭代过程,这个框架将满足一家虚构企业的需求。这里开发的示例框架可以很容易地进行修改以适合您的商业需求.

    SOA 和 Web 服务:简介

    SOA 是一种分布式的软件模型。SOA 的主要组件包括 服务、动态发现和 消息。

    服务是能够通过网络访问的可调用例程。服务公开了一个接口契约,它定义了服务的行为以及接受和返回的消息。术语 服务常与术语 提供者互换使用,后者专门用于表示提供服务的实体。

    接口通常在公共注册中心或者目录中发布,并在那里按照所提供的不同服务进行分类,就像电话簿黄页中列出的企业和电话号码一样。客户(服务消费者)能够根据不同的分类特征通过动态查询服务来查找特定的服务。这个过程被称为服务的 动态发现。

    服务消费者或者客户通过 消息来消费服务。因为接口契约是独立于平台和语言的,消息通常用符合 XML 模式的 XML 文档来构造。

    下面的 图 1说明了 SOA 中的不同角色。


    图一

    Web 服务作为 SOA

    Web 服务建立在开放标准和独立于平台的协议的基础之上。Web 服务通过 HTTP 使用 SOAP(一种基于 XML 的协议),以便在服务提供者和消费者之间进行通信。服务通过 WSDL(Web Service Definition Language)定义的接口来公开,WSDL 的语义用 XML 定义。UDDI 是一种语言无关的协议,用于和注册中心进行交互以及查找服务。所有这些特性都使得 Web 服务成为开发 SOA 应用程序的优秀选择。

    使用 J2EE 1.4 平台开发 SOA/Web 服务框架

    1.4 版的 J2EE 平台通过新的 JAX-RPC 1.1 API 提供了完整的 Web 服务支持,这种 API 支持基于 servlet 和企业 bean 的服务端点。JAX-RPC 1.1 基于 WSDL 和 SOAP 协议提供了与 Web 服务的互操作性。J2EE 1.4 平台也支持 Web Services for J2EE 规范(JSR 921),后者定义了 Web 服务的部署需求并利用了 JAX-RPC 编程模型。除了几种 Web 服务 API 之外,J2EE 1.4 平台还声称支持 WS-I Basic Profile 1.0。WS-I Basic Profile 标准让 Web 服务克服了不同编程语言、操作系统和供应商平台之间的障碍,从而使多种应用程序之间能够交互(关于 WS-I 的更多信息,请参阅 参考资料部分。)这意味着除了平台独立性和完整的 Web 服务支持之外,J2EE 1.4 还提供了跨平台的 Web 服务互操作性。

    在 J2EE 1.4 下,Web 服务客户可以通过两种方式访问 J2EE 应用程序。客户可以访问用 JAX-RPC API 创建的 Web 服务;在幕后 JAX-RPC 使用 servlet 来实现 Web 服务。Web 服务客户也可以通过 bean 的服务端点接口访问无状态会话 bean。Web 服务客户不能访问其他类型的企业 beans。第二种选择——公开无状态 EJB 组件作为 Web 服务——有很多优势:

    利用现有的业务逻辑和流程:在许多企业中,现有的业务逻辑可能已经使用 EJB 组件编写,通过 Web 服务公开它可能是实现从外界访问这些服务的最佳选择。EJB 端点是一种很好的选择,因为它使业务逻辑和端点位于同一层上。 

    并发支持:作为无状态会话 bean 实现的 EJB 服务端点不必担心多线程访问,因为 EJB 容器必须串行化对无状态会话 bean 任何特定实例的请求。 

    对服务的安全访问:企业 beans 允许在部署描述符中声明不同方法级别的安全特性。方法级别角色被映射到实际的主体域(principal domain)。使用 EJB 组件作为 Web 服务端点,把这种方法级别的安全性也带给了 Web 服务客户。

    事务问题:EJB 服务端点在部署描述符规定的事务上下文中运行。容器处理事务,因此 bean 开发人员不需要编写事务处理代码。

    可伸缩性:几乎所有 EJB 容器都提供了对无状态会话 bean 群集的支持。因此当负载增加时,可以向群集中增加机器,Web 服务请求可以定向到这些不同的服务器。通过把 Web 服务模型化为 EJB 端点,可以使服务具有可伸缩性,并增强了可靠性。

    池与资源管理:EJB 容器提供了无状态会话 bean 池。这改进了资源利用和内存管理。通过把 Web 服务模型化为 EJB 端点,这种特性很容易扩展,使 Web 服务能够有效地响应多个客户请求。
记住所有这些优点,下一节将展示如何在体系结构中将无状态 EJB 组件公开为 Web 服务。

    设计 SOA/Web 服务框架

    比方说有一家公司,它的各种系统(比如支付、财务和发票系统)需要彼此交互。此外,其中一些应用程序还需要对外界公开,以便不同的业务合作伙伴与它们进行交互。您还需要为各种应用程序(如输入发票的各种数据输入操作或者查看支付的状态)设计基于 Web 的解决方案。最佳选择就是设计一种松散耦合的基于服务的系统。这些服务应该得到开放标准的支持,这样任何业务合作伙伴都可以调用它们。

    这些方面的考虑将使您转向 Web 服务 /SOA 框架,通过无状态 EJB 组件把各种服务和业务流程公开为 Web 服务。下面的 图 2说明了企业内部应用的 SOA 框架。


    图二



 下面列出了 SOA 框架中进行交互的各种组件。这是一种典型的 MVC 2 框架。

     客户(Client):用户通过 Web 浏览器与不同的应用程序交互,浏览器作为应用程序的客户。比如,出纳部门的用户可能要输入帐单细节并把信息提交给应用程序。可以使用 JSP 页面和 XHTML 来呈现客户页面。

    应用程序控制器(Application controller):应用程序控制器是您的主控制器 servlet。它负责初始化、委派请求和响应请求处理程序。

    请求处理程序(Request processor):这是一个 Java 类,通过调用相应的请求执行程序完成要求的处理,对请求进行预处理。这种调用采用命令模式。

    请求执行程序(Request handlers):请求执行程序完成具体请求的活动,比如与服务交互,向不同的企业信息系统(enterprise information systems,EIS)增加或检索信息。请求执行程序依靠业务定位程序发现相应的服务,然后通过这些服务访问需要的 EIS 信息。
 
    业务定位程序(Business locators):这些程序负责隐藏查找服务的复杂性,并提供缓存逻辑。业务定位程序可以采用多种形式,比如 Web 服务定位程序、EJB 组件定位程序或者 JMS 定位程序。

    会话 Facades(Session Facades):通过聚合来自多个系统或服务的方法,简化复杂对象的视图。会话 facades 是 EJB Web 服务方法的包装器。

    EJB Web 服务(EJB Web services):根据 EJB 1.4 规范,Web 服务端点可以模型化为无状态的会话 bean。如前所述,这种技术有许多优势。

    数据访问接口(Data access interfaces):使用不同的技术(比如 EJB-CMP、JDO、DAO)和不同的持久性技术访问 EIS,所使用的访问技术取决于接口需求以及获取、插入或更新的数据量。这一层负责与 EIS 进行交互,并以相应的 EJB Web 服务方法所期望的格式把数据返回给这些方法。

    MQSeries/JCA/CCF:现有的基于主机的服务可以公开为 Web 服务,从而向外界展示它们。Web 服务客户使用基于 HTTP 的 SOAP 协议与 EJB Web 服务交互。EJB 方法通过 JMS 协议向 MQSeries 队列发送请求。(使用 MQSeries 是与基于主机的应用程序交互的一种方式。)主机端的 MQSeries 服务器触发相应的基于 COBOL 的程序,后者为与后台系统(比如 IMS DC)进行交互提供必要的逻辑。然后这些程序把响应返回到队列中,应用程序逻辑检索这些响应并返回给 EJB 方法。SOAP 消息可以通过不同协议进行传输,比如 HTTP、HTTPS 和 JMS,但为了统一起见,本例子只使用 HTTP 和 HTTPS。
这些组件提供了企业内部应用程序面向服务体系结构的基础。接下来讨论把服务向外界公开。

    向外界公开服务

    如果准备向外部用户公开服务,您需要某种安全约束来保证只有授权的用户才能访问服务。一种方法是提供另外的 Web 服务层,过滤掉禁用的 Web 服务请求,并提供登录和安全约束。这种过滤方式还应提供一种工具,向每一客户只公开授权给该用户的服务子集。


    图 3说明了企业外部应用的面向服务体系结构。它向外界公开了细粒度的服务。

    以下是这种体系结构的基本功能单元:

    外部客户(External clients):可以包括基于 Web 的客户、移动客户或者使用 .NET 环境、Perl 或其他编程语言编写的客户。所有这些客户都为不同的服务发送请求。只要遵循 WS-I Profiles 就不会出现互操作性的问题。

    企业防火墙(Corporate firewall):根据其安全策略,这家公司在 intranet 和 Internet 之间架起了防火墙,对收到的分组信息进行限制。

    Web 服务网关(Web Services Gateway):本例中,我选择使用 WebSphere Application Server 5.0 中的 Web Services Gateway 产品作为公开外部服务的网关。(关于该产品的更多信息,请参阅 参考资料。) Web Services Gateway 是一种中间件产品,在调用 Web 服务时提供了 Internet 和 intranet 之间的中间框架。使用 Web Services Gateway,开发人员和 IT 经理可以安全地对外公开 Web 服务,防火墙之外的客户也能调用这些服务。它包括一个服务管理模型(部署、取消部署,等等)和过滤器(对流经网关的请求和响应起作用的自定义代码)。它只处理收到的 SOAP/HTTP 请求,通过网关的请求可能发送给 Java 类、EJB 组件或者 SOAP 服务器(该服务器甚至还可能是另一个网关)。它可以为单个的 Web 服务方法提供保护(基本授权),也可以保护整个网关。使用 Web Services Gateway,来自客户的请求可以被转换成服务所要求的任何消息协议。例如,客户的请求可能是 HTTP 上的 SOAP,但在内部可以使用 JMS 协议上的 SOAP,Web Service Gateway 能够提供从一个协议到另一个协议的转换。

    EJB 服务(EJB services):EJB 服务没有任何变化。过程的其他部分和 图 2所示体系结构提供的基于 intranet 的服务类似。

    使用 EJB 组件实现粗粒度的服务

    迄今所见到的过程都是向客户公开细粒度的 Web 服务。只要每个业务服务作为单个业务过程执行,这种设置就能很好地工作。但是假设客户要进行在线资金转移,这种情况下提供单一的、粗粒度的接口显然更加合理,让用户提供所有必要的信息,包括传输的金额、发出和接收的银行信息,等等。此外,这类情形中验证必须在执行任何业务逻辑之前完成。在设计 Web 服务方法时必须考虑到这些问题,还要记住除了网络调用之外还有解析与规划 XML 请求和响应的开销。

    考虑到这些因素,可以把 Session Facades 模型化为 EJB Web 服务端点。Session Facades 可以在把请求委派给相应的 Web 服务方法之前首先验证请求。这样,您就可以向 Web 服务客户提供粗粒度的服务。 


    图 4说明了企业外部应用的面向服务体系结构的下一次迭代过程。这个版本的体系结构向外界公开粗粒度的服务。

    这里,主要的实现仍然和 图 3 中所示的相同。唯一的区别在于已经公开了 Session Facades 作为 Web 服务端点。EJB Web 服务可以模型化为本地接口而不是远程接口。使用会话 facades 和方法级安全性,可以限制要执行的服务。使用 Web Service Gateway 也能为 Web 服务客户施加安全措施。根据需要,可以实现粗粒度服务和细粒度服务的某种结合,通过调整 Web 服务网关中间件来向外部客户公开两种服务。(关于使用 Session Facades 与企业 Web 服务的更多信息,请参阅 参考资料。)

    结束语

    采用 WSDL 文件形式的 Web 服务接口可以发布到商业注册中心,从而使客户能够动态查找这些接口。如果交易伙伴已经知道这些服务,也不一定要进入商业注册中心,但是全球服务需要公共注册中心,以便客户能够查找可用的服务。例如,各个航空公司可以把它们的机票价格服务放在注册中心,普通客户可以发现所有这类服务,并查找航空公司所提供的最低票价。

    我希望本文能够有助于您开始使用 Web 服务和新的 J2EE 1.4 规范所提供的特性构建面向服务的体系结构。您可以修改和调整本文所述的 SOA Web 服务框架以适应您的业务需要。