楼主: lastwinner

[转载] 面向 Java 开发人员的 Ajax

[复制链接]
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
41#
 楼主| 发表于 2006-7-5 21:34 | 只看该作者
模板的问题

另一方面,现在我需要为每个不同视图创建一个新 JSP,而不能仅仅把需要的对象图组织起来并序列化它。从设计的角度来说,许多人可能会有争议,认为这无论如何是件好事,因为这意味着正式地考虑服务器要生成的文档类型。而且,因为我现在要处理通用的模板环境,而不是特定于 XML 的 API,所以确保标记匹配、元素和属性的顺序正确以及 XML 实体(例如 < 或 &)正确转义就成了我的责任。JSP 的核心 out 标记使后面这项工作变得很容易,但是不是所有的模板技术都提供了这样的机制。最后,没有方便的途径可以在服务器端根据方案检验生成的 XML 文档的正确性,但这毕竟不是要在生产环境中做的事,可以方便地在开发期间处理它。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
42#
 楼主| 发表于 2006-7-5 21:34 | 只看该作者
不用 XML 的响应数据

迄今为止,我介绍的所有技术都用 XML 文档的形式生成服务器响应。但是,XML 有一些问题。其中一个就是延迟。浏览器不能立即解析 XML 文档并生成 DOM 模型,所以这会降低某些 Ajax 组件需要的“迅捷”感,特别是在较慢的机器上解析大型文档的时候更是如此。“现场搜索”就是一个示例,在这种搜索中,当用户输入搜索术语时,就会从服务器提取搜索结果并显示给用户。对于现场搜索组件来说,迅速地响应输入是非常重要的,但是同时它还需要迅速而持续地解析服务器的响应。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
43#
 楼主| 发表于 2006-7-5 21:34 | 只看该作者
延迟是一个重要的考虑因素,但是避免使用 XML 的最大原因是差劲的客户端 DOM API。清单 5 显示了使用跨浏览器兼容的方式通过 DOM 得到某个值的时候,通常不得不面对的困难。


清单 5. 在 JavaScript 中导航 XML 响应文档

[php]                               
// Find name of first item in customer's last order
var orderHistoryDoc = req.responseXML;

var orders = orderHistoryDoc.getElementsByTagName("order";
var lastOrder = orders[orders.length - 1];

var firstItem = lastOrder.getElementsByTagName("item"[0];
var itemNameElement = firstItem.firstChild;

var itemNameText = itemNameElement.firstChild.data;

[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
44#
 楼主| 发表于 2006-7-5 21:35 | 只看该作者
当元素中间存在空白时,情况就变得更加复杂,因为每个元素的 firstChild 经常是个空白文本节点。现在有 JavaScript 库可以缓解处理 XML 文档的麻烦。这些库包括 Sarissa (请参阅 参考资料)和 Google-ajaXSLT,这两个库都把 XPath 功能添加到了大多数浏览器中。
但是,想想替代方案还是值得的。除了 responseXML 之外,XMLHttpRequest 对象还提供了名为 responseText 的属性,这个属性只是以字符串的方式提供服务器的响应体。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
45#
 楼主| 发表于 2006-7-5 21:36 | 只看该作者
responseText 属性

当服务器需要向客户机发送非常简单的值时,responseText 特别方便,它可以避免 XML 导致的带宽支出和处理支出。例如,简单的 true/false 响应可以由服务器以纯文本方式返回,可以是逗号分隔的简单的名称或数字列表。但是,一般来说,最好不要在同一个应用程序中把 XML 响应和纯文本响应混合使用;保持单一数据格式可以让代码抽象和重用更加简单。

responseText 与 XML 响应数据结合时也会有用。在只需要从响应文档中提取单一值的场景中,“欺骗性”地把 XML 当作文本字符串,而不把它当作结构化的文档对待,会更方便。例如,清单 6 显示了如何用正则表达式从顾客的订单历史中提取第一笔订单的日期。不过,这实际是种花招,一般不应当依赖 XML 文档的词汇表达。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
46#
 楼主| 发表于 2006-7-5 21:36 | 只看该作者
清单 6. 用正则表达式处理 XMLHttpRequest 的 responseText 对象

[php]                               
var orderHistoryText = req.responseText;
var matches = orderHistoryText.match(/<date>(.*?)<\/date>/);

var date = matches[1];
.....
[/php]


在某些情况下,采用即时方式使用 responseText 会比较方便。但是,理想情况下,应当有种途径,可以用一种能够让 JavaScript 轻松导航、却没有 XML 处理支出的格式表示复杂的结构化数据。幸运的是,确实存在这样一种格式。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
47#
 楼主| 发表于 2006-7-5 21:37 | 只看该作者
JavaScript 对象标注

实际上,JavaScript 对象的大部分都由联合数组、数字索引数组、字符串、数字或者这些类型的嵌套组合而成。因为所有类型都可以用 JavaScript 直接声明,所以可以在一条语句中静态地定义对象图。清单 7 使用 JSON 语法声明了一个对象,并演示了如何访问这个对象。大括号表示联合数组(即对象),它的键 -值组合由逗号分隔。方括号表示数字索引数组。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
48#
 楼主| 发表于 2006-7-5 21:37 | 只看该作者
清单 7. 用 JSON 在 JavaScript 中直接声明一个简单对象

[php]                               
var band = {
  name: "The Beatles",
  members: [
    {
      name: "John",
      instruments: ["Vocals","Guitar","Piano"]
    },
    {
      name: "Paul",
      instruments: ["Vocals","Bass","Piano","Guitar"]
    },
    {
      name: "George",
      instruments: ["Guitar","Vocals"]
    },
    {
      name: "Ringo",
      instruments: ["Drums","Vocals"]
    }
  ]
};

// Interrogate the band object
var musician = band.members[3];
alert( musician.name
        + " played " + musician.instruments[0]
        + " with " + band.name );

...............
[/php]

既然 JSON 是一个有趣的语言特性,那么它对 Ajax 有什么意义呢?妙处在于可以用 JSON 在 Ajax 服务器响应中通过网络发送 JavaScript 对象图。这意味着在客户端可以避免使用笨拙的 DOM API 对 XML 进行导航 —— 只需要分析 JSON 响应,就会立即得到可以访问的 JavaScript 对象图。但是,首先需要把 JavaBean 变成 JSON。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
49#
 楼主| 发表于 2006-7-5 21:38 | 只看该作者
从 Java 类产生 JSON
不同 XML 生成技术所具有的优缺点也适用于 JSON 的产生。而且可以证明,存在需要再次使用表示模板技术的情况。但是,使用 JSON 在理念上更接近于在应用层之间传递序列化的对象,而不是创建应用程序状态的视图。我将介绍如何用 org.json 这个 Java API 在 Java 类上创建 toJSONObject() 方法。然后,就可以把 JSONObject 简单地序列化成 JSON。清单 8 反映了 清单 1 讨论的 XML,显示了 Order 类的 toJSONObject() 实现。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
50#
 楼主| 发表于 2006-7-5 21:38 | 只看该作者
清单 8. Order 类的 toJSONObject() 方法实现

[php]                               
public JSONObject toJSONObject() {

  JSONObject json = new JSONObject();
  json.put("id",id);
  json.put("cost",getFormattedCost());
  json.put("date",date);

  JSONArray jsonItems = new JSONArray();
  for (Iterator<Item> iter =
   items.iterator() ; iter.hasNext() ; ) {
    jsonItems.put(iter.next().toJSONObject());
  }
  json.put("items",jsonItems);

  return json;
}

.........
[/php]

可以看到,org.json API 非常简单。 JSONObject 代表 JavaScript 对象(即联合数组),有不同的 put() 方法,方法接受的 String 键和值是原生类型、String 类型或其他 JSON 类型。JSONArray 代表索引数组,所以它的 put() 方法只接受一个值。请注意在清单 8 中,创建 jsonItems 数组,然后再用 put() 把它附加到 json 对象上;可以用另外一种方法做这项工作,就是对每个项目调用 json.accumulate("items",iter.next().toJSONObject());。accumulate() 方法与 put() 类似,区别在于它把值添加到按照键进行识别的索引数组。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表