JBoss Seam (POJO without EJB) 后台 + ExtJS 前台完整例子(八)
1.引言
AJAX应用具有表现力丰富、更加互动和更加迅速的响应等特点,这些特点都是通过使用XMLHttpRequest对象来动态的载入数据而获得的,而不是重新载入新的页面。在应用这一抽象层次,需要有比直接操作XMLHttpRequest对象更加方便的前后台通讯机制。
本文介绍Java后台和前后的几种常用的通讯机制和实现方法。
2. JSON
JSON(JavaScript Object Notation) 是前后台数据交换的一种格式。由于它可以直接转换为JavaScript的内部数据结构,所以成为AJAX应用的 首选数据交换格式。
在ExtJS中,使用数据集作为数据源的器件,如网格、下拉列表等,都规定了能够接受的后台JSON数据格式。在《ext tutorial》的第2章“ 2. 震撼吧!让你知道ext表格控件的厉害。” 中, 对作为网格数据源的JSON格式有非常清晰的描述。
3. DWR/JBoss Seam Remoting
用Java作为后台的开发人员有福了!使用 DWR(Direct Web Remoting) 或 JBoss Seam Remoting后,我们可以直接调用后台的方法,就像调用本地JS方法一样。还有比这样做更加简单的方法吗?!
DWR和JBoss Seam Remoting是两种十分类似的技术,在 divo.js 中,提供了通用的方法屏蔽这两种技术的差别:
js 代码
- /**
- * 远程[异步]调用服务器端方法
- * @param {String} method 格式为:类名.方法名
- * @param {Function} callback 回调函数
- * @param {Array} params 传递参数
- */
- rmtCallAsync : function(method, callback, params) {
- 。。。
- }
例如:
js 代码
- var onLogin = function(retValue) {
- if (retValue) {
- window.location = Divo.getFullPath()+"app/sample/main.seam";
- return;
- }
- Divo.error("登录失败");
- }
- Divo.wait("正在登录...");
- Divo.rmtCallAsync("sampleFacade.login",onLogin,[name,pswd]);
不管后台是使用DWR, 还是使用 JBoss Seam Remoting, 都可以使用相同的 Divo.rmtCallAsync 调用格式.
4. 同步还是异步?
AJAX的第一个字母虽然代表了异步(asynchronous),但使用XMLHttpRequest对象时仍然可以选择同步:
java 代码
- var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
- xmlhttp.Open("POST", "http://myserver/...", false); //第3个参数为false表示同步,true表示异步
同步 AJAX 下, JS 将在服务器返回结果后才执行后续程序。当这种请求被处理时, 普通浏览器会进入冻结状态。虽然绝大多数此类响应都非常迅速, 并不会造成麻烦, 但是如果请求和/或文件传输过程出现故障, 用户的浏览器就可能无法响应多达数分钟, 直至请求超时。
是否应该使用同步AJAX,一直存在着 争论。虽然更常用的是异步请求, 程序员也应该尽量使用异步操作,以提高程序的响应性。但在特定情况下,使用同步模式也是必要的,可以简化程序的设计。
DWR提供了进行同步操作的方法,但 JBoss Seam Remoting 则没有提供类似功能。显然,JBoss Seam Remoting的设计者在拒绝同步操作,我认为这样的设计并不合适。为此,我修改了 remoting.js 中代码,参见我的这个 帖子。
5. 通过JSON传送网格数据
在本项目中,从Java对象转换为JSON数据格式,采用了 JSONObject库。
JSONObject库的所有类文件,在 com.divo.core.json 包中。为了适应ExtJS对JSON格式的特殊要求,添加了若干类,设计上参照了这个ExtJS社区 帖子。
在 org.jboss.seam.example.divo.SampleServlet 类中,可以看到使用JSON传送网格数据的代码:
java 代码
- JSONDataReader jsonReader = new JSONDataReader();
- jsonReader.setRecordCount(lr.getTotalSize());
- if (lr.getData().size() > 0) {
- for (Booking obj : lr.getData()) {
- jsonReader.put(obj.toJSONObject());
- }
- }
- JSONUtil.buildJSON(request, response, jsonReader);
6. 通过JBoss Seam Remoting进行远程方法调用
本项目采用 JBoss Seam Remoting 进行远程方法调用. 后台设计采用了 外观模式.
在 org.jboss.seam.example.divo.SampleFacade 中, 需要被远程调用的方法,只要加上@WebRemote元注解即可. 例如:
java 代码
- @WebRemote
- public boolean login(String name,String password) {
- return userService.login(name,password);
- }
在Java类型转换方面, JBoss Seam Remoting 和 DWR 采用了不同的设计手法, 详细内容请参见Seam 2.0的参考手册。
7. 结语
JSON和远程方法调用两种前后台通讯机制, 使AJAX应用开发人员可以在更高的层次进行编程, 而不用关心
底层的通讯和数据交换细节. 从下一篇开始, 我将把主题转到后台的JBoss Seam框架.
附:下面是本系列所有文章的完整列表:
(1) 下载示例项目并安装运行
(2) 建立Eclipse开发环境
(3) 熟悉项目中与JSF相关内容
(4) 重新认识JS
(5) ExtJS之表单(Form)
(6) ExtJS之布局(Layout)
(7) ExtJS之网格(Grid)
(8) Java后台和前台的通讯机制
(9) Seam框架简化Java开发
(10) 分层架构设计
(11) 安全性
(12) 单元测试