【IT168 技术文章】
简介
Java EE 技术是 Java 语言平台的扩展,支持开发人员创建可伸缩的强大的可移植企业应用程序。它为应用程序组件定义了四种容器:Web、Enterprise JavaBean(EJB)、应用程序客户机和 applet。一个应用服务器规范详细描述了这些容器和它们必须支持的 Java API,这促使 Java EE 产品相互竞争,同时保证符合这个规范的应用程序可以在服务器之间移植
这个平台的最新版本 Java EE 5 已经于 2006 年 5 月发布。Java EE 5 主要关注提高开发人员的生产率,它提供了更简单的编程模型,而没有牺牲平台的任何功能。更简单的开发模型主要由两个机制提供 —— Java 注解和更好的默认行为。主要的功能性改进包括改进了 Web 服务支持以及在平台中集成了 JavaServer Faces(JSF)和 Java Standard Tag Library(JSTL)。
本文介绍 Java EE 5 中的特性,重点介绍自上一个 J2EE 版本以来的变化。(超出本文范围的改进包括 StAX API — 一个用来解析 XML 的 API — 和跨许多 API 的中小程度的改进。)我将全面讨论四个特性类别:Web 服务、Web 应用程序、企业应用程序以及管理和安全性。然后,为了避免读者觉得厌烦,我们讨论一个使用 Java EE 5 特性的小应用程序,以此说明新的开发模型如何简化面向服务架构(SOA) Web 应用程序的开发。
本文假设读者熟悉企业级软件系统,并希望全面了解 Java EE 5 的概况。了解 Java 编程和 J2EE 对于理解特性的意义会有帮助,但不是必需的。对示例应用程序的讨论涉及一些技术细节,有 J2EE(至少是 Java 编程)背景可能比较容易理解。
Web 服务技术
在 Java EE 5 中引入了注解(annotation)特性,这简化了复杂 Web 服务端点和客户机的开发,与以前的 Java EE 版本相比,代码更少,学习过程更短了。注解(最早在 Java SE 5 中引入)是可以作为元数据添加到代码中的修饰性代码。它们并不直接影响程序的语义,但是编译器、开发工具和运行时库可以通过处理它们生成额外的 Java 语言源文件、XML 文档或其他工件和行为,这些对包含注解的程序起辅助作用。在本文后面,会看到如何通过添加简单的注解,将常规的 Java 类转换为 Web 服务。
Web 服务支持方面的飞跃
Java EE 5 中 Web 服务支持的基础是 JAX-WS 2.0,它是一种替代 JAX-RPC 1.1 的技术。这两种技术都支持创建 REST 风格和基于 SOAP 的 Web 服务,而不必直接处理 Web 服务固有的 XML 处理和数据绑定细节。开发人员可以继续使用 JAX-RPC(这仍然需要 Java EE 5 容器),但是强烈建议迁移到 JAX-WS。刚开始学习 Java Web 服务的开发人员可以跳过 JAX-RPC,直接使用 JAX-WS。它们都支持 SOAP 1.1 over HTTP 1.1,所以完全兼容:JAX-WS Web 服务客户机可以访问 JAX-RPC Web 服务端点,反之亦然。
与 JAX-RPC 相比,JAX-WS 有许多优点。JAX-WS:
支持 SOAP 1.2 标准(以及 SOAP 1.1)。
支持 XML over HTTP。如果愿意,可以不使用 SOAP。(更多信息参见文章 “Use XML directly over HTTP for Web services (where appropriate)”。)
使用 Java Architecture for XML Binding(JAXB)作为数据映射模型。JAXB 完全支持 XML 模式,而且性能更好(更多信息见下文)。
为客户机和服务器引入了一个动态编程模型。客户机模型支持面向消息方式和异步方式。
支持 Message Transmission Optimization Mechanism(MTOM),这是一个用于优化 SOAP 消息传输和格式的 W3C 建议规范。
升级了 Web services interoperability(WS-I)支持。(它支持 Basic Profile 1.1;JAX-WS 只支持 Basic Profile 1.0。)
升级了 SOAP 附件支持。(它支持 Attachments API for Java [SAAJ] 1.3:JAX-WS 只支持 SAAJ 1.2。)
通过阅读文章 “Web 服务提示与技巧: JAX-RPC 与 JAX-WS 的比较”,可以进一步了解这些差异。
JAX-WS 中的 wsimport 工具自动地处理 Web 服务开发的许多细节,并以跨平台方式集成到构建过程中,这让开发人员可以将注意力集中于实现或使用服务的应用程序逻辑。它生成各种工件,包括服务、服务端点接口(SEI)、异步响应代码、基于 WSDL 错误的异常以及通过 JAXB 绑定到模式类型的 Java 类。
JAX-WS 还能够提高 Web 服务的性能。在文章 “Implementing High Performance Web Services Using JAX-WS 2.0”,对基于 JAX-WS 的 Web 服务实现(使用了 Java EE 5 中的另外两个 Web 服务特性 — JAXB 和 StAX)和基于 J2EE 1.4 中的 JAX-RPC 的服务实现做了性能对比。这项研究发现在不同负载下 JAX-WS 在各个功能领域产生了 40% 到 1000% 的性能改进。
Web 应用程序技术
除了现有的 JavaServer Pages 和 Servlet 规范,Java EE 5 引入了两种前端技术 — JSF 和 JSTL。JSF 是一组 API,支持以基于组件的方式开发用户界面。JSTL 是一组标记库,支持在 JSP 中嵌入过程式逻辑、对 JavaBean 的访问方法、SQL 命令、本地化格式指令和 XML 处理。JSF、JSTL 和 JSP 的最新版本支持一种统一表达式语言(expression language,EL),这使这些技术更容易集成在一起。
JSF 1.2
JSF 为常见的 UI 问题提供了内置支持,比如组件状态管理、事件处理、导航、用户输入检验和国际化。有经验的开发人员可以创建定制的强大的可重用组件,还可以为 Web 浏览器之外的其他客户机设备创建定制的组件。技术经验不足的用户可以在 Sun Java Studio Creator 等可视编程环境中重用定制组件,包括用于 HTML 界面的默认 JSF 标记库。这让编程新手也能够创建复杂的 Web 表示层。
在开放源码领域和受许可协议限制的软件领域中,第三方 JSF 组件越来越多了。在 Web 上搜索 “JSF components” 或 “JSF component libraries” 会找到几十种组件。许多组件都依赖于 Asynchronous JavaScript + XML(Ajax)技术,这种技术是 “Web 2.0” 运动背后的主要驱动力。Web 程序员可以使用它们创建出比传统 Web 应用程序更好的用户体验,同时避免了从头编写 Ajax 组件的麻烦。
JSP 2.1
JSP 技术是从 J2EE 2.1 开始出现的。它使用 Java Servlet 规范支持声明式的 UI 编程。它支持以文档形式编写 UI,Web 应用程序容器将这些文档转换为 Java servlet 并编译,然后调用它们来响应请求。这些文档通常将 JSP 指令和脚本片段与某种标记语言(比如 HTML)混在一起。JSP 可以使用老式语法(使用以 结束的特殊标记),也可以使用新的语法(良构的 XML)。它们通常作为 Model-View-Controller(MVC) UI 框架的 “View” 部分。
与以前的版本相比,JSP 2.1 和 JSF 1.2 之间的兼容性更好,这主要是因为它们的 EL 语法已经集成为统一 EL。EL 支持的操作包括:
在请求、会话和应用程序上下文中访问 JavaBean 的属性。
执行逻辑测试来做出各种选择,比如隐藏还是显示某个元素。
通过计算生成在 UI 中显示的数字和字符串。
过去,JSP 和 JSF EL 语法有差异,而且容器计算它们的方式也不一样。统一 EL 消除了这些差异,还增加了一些特性,比如:
一个可插入的框架,支持对 EL 的解释进行定制。
支持延期执行的表达式,JSP 标记处理器可以根据需要执行它们。
支持赋值操作,例如可以在 JSP 代码中用 EL 表达式设置 JavaBean 的属性。
对于 JSP 标记库开发人员来说,好消息是标记处理器现在支持用注解注入资源,所以大大简化了执行 Java Naming and Directory Interface(JNDI)所需的资源配置和代码。
JSTL 1.2
JSTL 已经存在多年了,但是在 Java EE 5 之前,Java EE 还不包含它。JSTL 标记支持在 JSP 中嵌入以下类型的元素:
过程式逻辑,比如循环和 if/else 结构。
对 JavaBean 的访问方法,这可以向 UI 提供动态数据并允许 UI 代码修改数据。
执行数据库访问的 SQL 命令。
格式化指令,可以根据特定的地区对 UI 输出进行格式化。
XML 处理,比如 Document Object Model(DOM)解析或 Extensible Stylesheet Language(XSL)转换。
JSTL 1.2 是一个维护版本,它支持统一 EL 并解决了在同一个 JSP 页面中混用 JSF 标记和 JSTL 迭代标记时遇到的问题。
Java Servlet 2.5
Java Servlet 规范是 Java Web 层技术的核心,它的历史与 Java EE 技术本身一样长。设计这个规范是为了提供一种高效率的基于组件的 Web 应用程序开发方法,并确保 Web 应用程序可以移植到实现这个规范的任何服务器上。
Java EE 5 所需的 Servlet 2.5 规范是一个维护版本,它对 2.4 版做了一些次要的改进。它在 Java 5 平台上引入了一些依赖项,还引入了一些注解,它们可以减少对 Web 应用程序部署描述符配置文件(web.xml)的配置需求。还增加了一些方便的配置特性,例如可以用通配符和多个 url-pattern 元素更灵活地配置 servlet。
企业应用程序技术
有大量技术属于企业应用程序的范围,其中许多在 Java EE 5 中没有变化或者不适合在本文中详细讨论。这里主要关注两个改进:对 EJB 开发的简化和新的持久化特性。
EJB 3.0
EJB 规范是 Java EE 平台的核心。它定义如何封装应用程序的业务逻辑,并以高度可伸缩、可靠且感知事务的方式分布业务逻辑,确保并发的数据访问不会破坏数据。
EJB 有三种基本类型:
会话 bean 分成两类:无状态 和有状态。无状态会话 bean 用于那些为单一客户机请求提供服务的业务逻辑任务。有状态会话 bean 维护客户机的 “会话状态”,适合处理那些跨越多个客户机请求的任务。会话 bean 不能在客户机之间共享。会话 bean 通常会操作一个或多个实体 bean。
实体 bean 代表持久化数据,数据通常是从数据库中装载的。实体 bean 可以在客户机之间共享,而且 EJB 规范提供了事务安全的机制,确保实体 bean 可以可靠地为多个并发客户机请求提供服务,而不会被破坏。实体 bean 可以自己管理持久化,也可以让容器来管理它(容器管理的持久化(container-managed persistence,CMP) )。
消息驱动 bean(MDB) 用来处理那些不要求客户机等待响应的客户机请求。它们通常与一个 Java Message Service(JMS)队列 — Java EE 5 中的另一种企业应用程序技术 — 进行交互,但是也可以以其他方式为异步客户机提供服务,客户机甚至可以不是用 Java 编写的。
在过去,EJB 的开发很复杂很麻烦,开发人员常常不得不依靠工具来管理实现 EJB 所需的所有接口和部署描述符。规范为业务逻辑代码规定了许多限制,要求扩展特定的类或实现特定的接口。为了获得一个简单的 EJB 引用,就需要许多样板代码。这些问题使 EJB 在开发社区中名声很差;在许多情况中,EJB 确实很糟糕。
EJB 3.0 大大改进了 EJB 编程模型,这是提高 Java EE 5 开发人员生产率的主要因素之一。EJB 现在可以是一个加了注解的 “普通 Java 对象(plain old Java object,POJO)”,它不需要扩展特定的类。它只需要实现一个远程接口,您可以自己定义这个接口,也可以让 IDE 自动生成它。不再需要部署描述符了,因为 EJB 容器可以从 EJB 上的注解提取出所需的所有信息。
本文的 实践:RideSynergy 应用程序 一节通过示例代码给出这些改进的具体示例。如果需要了解更深入的细节,可以在中找到两篇文章的链接,这两篇文章提供了更有说服力的示例,说明了这个最新版本对 EJB 开发的改进是多么显著。
Java Persistence API(JPA 1.0)
JPA 引入了一个用于 Java 对象持久化的对象-关系映射(object-relational mapping,ORM)框架。在开发它时主要考虑 EJB 的需要,但是它可以用于任何 Java 对象。可以使用注解指定哪些对象和字段应该持久化,以及它们应该映射到哪些数据库表和字段。JPA 支持一种与 SQL 相似的查询语言。这种查询语言可以:
定义参数化的查询,这种查询可以以有序列表形式接收参数(按索引号引用参数),也可以采用按名称引用的命名参数。
按照持久化实体之间的关系执行查询,而不需要 JOIN 语句(但是,如果您愿意,也可以使用 JOIN 语句)。
按照与 SQL 相似的方式指定搜索条件(比较操作符、LIKE 语句、BETWEEN 语句等等),定义如何对待结果集(使用 DISTINCT、ORDER BY、GROUP BY 等操作符)。
JPA 给 Java EE 平台提供了新功能,解决了与手工持久化和容器持久化相关的许多麻烦。
管理和安全性
Java EE 5 需要三个与以前版本相同的管理和安全性规范:
Application Deployment 提供一个用于将组件和应用程序部署到 Java EE 容器的 API。工具可以通过这个 API 将代码部署到 Java EE 5 容器中,而不需要重新启动容器。在开发期间,IDE 常常使用这个 API 支持快速的编写/测试/纠正循环。
Application Management 为容器管理的对象指定必需的属性和操作。它与多种行业标准管理协议兼容。
Authorization Contract for Containers(Java ACC)定义安全策略提供者的语义,以及如何授予对这个合约中的操作的访问权。它要求容器实现一些接口,使部署工具能够管理授权角色。
在 Java EE 5 中,这些规范都是维护版本(版本号都从 J2EE 1.4 中的 1.0 版升到 1.1 版),做了一些次要改进,这些超出了本文的范围。