使用 JAX-RS、JPA 和 Dojo 创建丰富的以数据为中心的 web 应用程序
使用 Java Persistence API 运行数据
很多 web 应用程序是以数据为中心 — 它们显示数据并允许用户新建或更新数据。这听上去很简单,但真到了一些基本操作,如在数据库中读写数据,情况却非常糟糕。尽管如此,Java Persistence API (JPA) 却极大地减少了必须编写的冗长的样板式代码。我们将看一个使用 JPA 的简单例子。
本文中,将开发一个简单的管理青年足球联赛的应用程序。开始时将建立一个简单的数据模型,用于跟踪球队及其队员。将使用 JPA 完全访问这些数据。以第一个数据模型?Team
?开始。清单 1?显示了此类。
Team
?数据模型类回头看看?清单 1?和?清单 2,所有代码都是通用的 JPA 代码。实际上曾使用的都是 JPA 注释和它的常量。对已使用的数据库和 JPA 实现没有什么特别的。正如在?清单 3?中看到的,persistence.xml 文件正是存放这些特定内容的地方。有一些出色的 JPA 实现可用,包括 OpenJPA 和 TopLink(见?参考资料)。已经使用过古老的 Hibernate,因此有几个 Hibernate 相关属性已经指定。这些多数都是简单易懂的,如 JDBC 驱动器和 URL,而且是很有用的,如通知 Hibernate 登陆到正在执行的 SQL (一些您肯定不想放在产品环境中的内容,但对于调试却很重要)。
在?清单 3?中,您还会注意到使用了 Apache Derby 数据库。实际上,使用的是数据库的嵌入式版本。您不必单独启动数据库,且担心配置。此外,在连接 URL 中您也指出应该自动创建数据库,并且您也通知 Hibernate 自动创建模式(这是?
hibernate.hbm2ddl.auto
属性)。因此如果只运行应用程序,可以创建数据库及表。这有益与开发,但当然您会希望产品系统设置不一样。现在数据模型代码已经生成,并可通过 JPA 访问,我们将查看开放该数据,以便应用程序能使用它。回页首
使用 JAX-RS 对数据的 RESTful 访问
如果是五年前创建该应用程序,现在可能会使用一些 Java Server Pages (JSPs) 或 Java Server Faces (JSFs) 或一些其他模板技术。不需要服务器上为该应用程序创建 UI,而是使用 Dojo 在客户端创建。所需要做的就是让客户端代码使用 Ajax 来访问数据。也可使用模板解决方案来解决这类问题,但使用 Java API for RESTful Web Services (JAX-RS) 要简单得多。一开始我们创建一个类,用于读取数据库中所有?
Teams
?以及创建新的?Teams
。清单 4?显示该类。
清单 4.?Teams
?的数据访问类如您在?清单 7?中所见,应用程序中只有一个 servlet 声明。该 servlet 是由 Jersey 所提供的,这是使用的 JAX-RS 实现。传递一个初始化参数给 servlet — 包中含有您希望 JAX-RS 了解的所有类。本例中,有一个存放数据模型的包和一个存放数据访问对象的包。您希望能找到这些模型,以便 JAX-RS 能够将其转换为 JSON。当然,需要找到 DAO 以便 JAX-RS 能将请求路由到它们。最后,请注意 servlet 映射。这里指定了您的 URL 路径的 /resources 部分。现在已经准备好在客户端使用所有后台代码创建一个使用 Dojo 的 UI。
回页首
利用客户端的 REST 和 Dojo
Dojo 工具箱提供了几乎所有构造 web 应用程序客户端所需的库或工具。您会看到它在使用 Ajax、表单、JSON 和创建 UI 小部件时如何提供帮助。(它可以做的更多,而这恰好是在该简单例子中您所需要的。)它是如此庞大的一个系统,您可能想要下载完整的工具箱并根据您应用程序所需自定义构造。对于本应用程序示例,您可以换用 Google Ajax API 来访问您所需要的工具箱的各个部分。这很方便,而且具有性能优势,因为 Google 的 Dojo 版本是通过 Google 自己的高效内容发布网站(CDN)提供的。
您的应用程序是以数据为中心的,因此开始时可以加入一些数据。我们将使用 Dojo 创建 UI 来添加?
Teams
。清单 8?显示所有您所需要的代码。
清单 8. 使用 Dojo 添加?Teams
注意在?清单 8?中,您引用了来自 Google CDN 的基础 Dojo 库。完成之后,您就可以使用?
dojo.require
?函数请求 Dojo 额外部分(见?清单 8?中代码底部)。请注意您刚创建了一个普通 HTML 表单,但使用了一些额外的 Dojo 相关属性。这告诉 Dojo 在可视化元素中加入额外的样式,并在对应的 DOM 元素中加入额外功能。告诉 Dojo 一旦其他东西加载(所有 Dojo 组件)就执行?init
?函数。此函数中,使用?dijit.byId
?函数取得表单中按钮的事件处理函数。Dijit
?是 Dojo 的小部件库。可以使用?dojo.byId
?来根据 ID 引用任何 DOM 元素,但类似的?dijit.byId
?会赋给小部件额外的功能(如果元素标记为 widget,则如?清单 8?中按钮所示)。然后可以使用 Dojo 为按钮点击关联一个事件处理函数。事件处理函数停止表单提交,并使用在?
dojo.xhrPost
?函数中使用 Ajax。该函数使?POST
?HTML 表单很容易。它通过检测 HTML 表单的?action
?属性区分 Ajax 客户端。它还读取所有的表单元素并将它们传递到 Ajax?POST
。当它接收到服务器返回的响应,它就调用传递给?xhrPost
?的?load
?函数。请注意,通过设置传递给?xhrPost
?函数的handleAs
?属性来返回 JSON。很快将看到?addTeam
?函数,但可以直接传入数据对象,因为已将 JSON 数据安全解析成可用的 JavaScript 对象。该?addTeam
?函数将与另一表单联合使用,来添加?Players
。清单 9?显示的是表单的 HTML。
清单 9. 添加?Player
?表单该表单,与?清单 8?中的一样,是一个有效的 HTML 表单。尽管如此,元素中却添加了 Dojo 特定属性。请注意,有一个?
SELECT
?元素,它将作为?Teams
?的下拉列表,让用户可选择将?Player
?加入哪个?Team
。这是需要从服务器加载的动态数据。请注意在启动时还加入了另一个函数 —?loadTeams
?函数。它用于从服务器加载球队。清单 10?显示了该函数,以及?addTeam
?函数,如您所见,它在?清单 9曾被引用。
清单 10.?loadTeams
?和?addTeam
?函数这里,再次用到了 Dojo 的 Ajax 工具访问数据,此工具由先前创建的 JAX-RS 终端所提供。这次使用的是?
dojo.xhrGet
,它向 Ajax 终端发出 HTTP?GET
?请求。在此例中,需要指定它的 URL,否则它与?清单 9?中所看到的?xhrPost
?一样。最后,是?addTeam
?方法。这里再次使用 Dojo 小部件的额外功能向显示球队的下拉列表轻松添加新选项。现在已经看到球员表单是如何创建的,再看看处理提交的代码(见?清单 11)。
清单 11. 添加新?Player
这段代码将向?
PlayerDao.addPlayer
?方法提交数据,该方法您已在前面的?清单 6?中见过。这段代码预计将?Player
?对象序列化成 JSON 数据结构。首先,您再次使用 Dojo 来包装表单上按钮点击处理函数。下一步,使用 Dojo 的函数?dojo.formToObject
?来将表单中数据转换成 JavaScript 对象。然后稍微修改 JavaScript 对象,以匹配服务器能接收的结构。然后使用 Dojo 的?dojo.toJson
?函数将它转换成 JSON 字符串。现在它传给?dojo.xhrPost
,与?addTeam
?表单提交方式一样。请注意,您添加了 HTTP 头部?Content-Type
?来保证它路由到?PlayerDao.addPlayer
?方法。
xhrPost
?也有一个?load
?函数,它会在 Ajax 请求从服务器携带成功响应返回后调用。本例中,它会清空页面上名为?gridContainer
?的元素,并调用名为?gridContainer
?的元素,loadPlayers
?的函数。这是另一个用来显示所有球员的 Dojo 小部件。清单 12?显示用于此目的的 HTML 和 JavaScript 。
清单 12. Player grid HTML 和 JavaScript清单 12?显示了 Dojo 的?
DataGrid
?小部件。它是 Dojo 中一个更丰富的小部件,因此也需要额外的 CSS。要新建一个 grid,要做两件事。首先,需要创建数据源。本例中,是来自服务器的 JSON 数据,因此创建一个新的?JsonRestStore
?对象,并将它指向将会产生数据的服务器 URL。然后覆盖?_processResults
。只需要这样做,因为它能预计接收 JSON 数组的数据,并且 JAX-RS 终端将会生成更复杂一点的对象(它有一个属性,名为?player
,它的值是?JsonRestStore
?预计接收的 JSON 数组)。grid 还需要布局元数据,以描述显示哪些列,以及 JavaScript 对象对应的属性是什么。然后就可以创建 grid 并将它放入 DOM 目录树中。现在已完成足球应用程序示例,有很多方法显示联赛中的球员。您可以轻松扩展此处的简单示例,如添加球员编辑功能,对 grid 排序,甚至可以加入更多的数据,如比赛和结果。
回页首
结束语
本文演示了快速创建丰富的、以数据为中心的 web 应用程序的方法。使用了几项关键技术移除服务器端和客户端的繁杂的样板式代码:JPA、JAX-RS 和 Dojo。很多情况下,可以直接使用默认的惯例设置进一步减少 web 应用程序中的代码量。其结果是使用最少的代码创建非常先进的 web 应用程序。使用到的所有技术都是可扩展和具有量产品质的,因此您可放心扩展此应用程序示例(或您自己的应用程序),直接用于更加健壮的用例。更棒的是没有壁垒。使用的是服务器端的开放标准。例如,可以轻松转换数据库技术。在前台使用 REST 和 JSON,这意味着可以使用不同的 UI 套件,或者可以轻松连接上移动客户端。
回页首
下载
描述名字大小下载方法文章源代码SoccerOrg.zip14KBHTTP关于下载方法的信息
参考资料
学习
获得产品和技术
讨论