科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道结合Direct Web Remoting使用Ajax3

结合Direct Web Remoting使用Ajax3

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

虽然令人兴奋,但是把 Ajax 功能添加到应用程序可能意味着大量的艰苦工作。在本文中Philip McCarthy 介绍了如何使用Direct Web Remoting(DWR)直接把 JavaBean 的方法公开给 JavaScript 代码并自动进行 Ajax 的繁重工作。

作者:Philip McCarthy 来源:IT专家网 2008年6月1日

关键字: AJAX 使用 结合 java

  • 评论
  • 分享微博
  • 分享邮件
清单 6 是扩展的 dwr.xml 配置文件,包含 Cart 类进行远程所需要的额外配置:

  清单 6. 修改过的 dwr.xml 包含了 Cart 类

<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
    "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
  </allow>
    </create creator="new" javascript="catalog">
      </param name="class"
        value="developerworks.ajax.store.CatalogDAO"/>
      </include method="getItem"/>
      </include method="findItems"/>
    <//create>
    </convert converter="bean"
      match="developerworks.ajax.store.Item">
      </param name="include"
        value="id,name,description,formattedPrice"/>
    <//convert>
    </create creator="new" scope="session" javascript="Cart">
      </param name="class"
        value="developerworks.ajax.store.Cart"/>
      </include method="addItemToCart"/>
      </include method="getCart"/>
    <//create>
    </convert converter="bean"
      match="developerworks.ajax.store.Cart">
      </param name="include"
        value="simpleContents,formattedTotalPrice"/>
    <//convert>
  <//allow>
</dwr>

  在这个版本的 dwr.xml 中,我添加了 Cart 的 creator 和 convertor。create 元素指定应当把 addItemToCart() 和 getCart() 方法远程化,而且重要的是,生成的 Cart 实例应当放在用户的会话中。所以,购物车的内容在用户的请求之间会保留。

  Cart 的 convert 元素是必需的,因为远程的 Cart 方法返回的是 Cart 本身。在这里我指定在 Cart 的序列化 JavaScript 形式中应当存在的成员是 simpleContents 这个图和 formattedTotalPrice 这个字符串。

  如果对这觉得有点儿不明白,那么只要记住 create 元素指定的是 DWR 客户可以调用的 Cart 服务器端方法,而 convert 元素指定在 Cart 的 JavaScript 序列化形式中包含的成员。

  现在可以实现调用 Cart 的远程方法的客户端代码了。

  调用远程的 Cart 方法

  首先,当商店的 Web 页首次装入时,我想检查保存在会话中的 Cart 的状态,看是否已经有一个购物车了。这是必需的,因为用户可能已经向 Cart 中添加了商品,然后刷新了页面或者导航到其他地方之后又返回来。在这些情况下,重新载入的页面需要用会话中的 Cart 数据对自己进行同步。我可以在页面的 onload 函数中用一个调用做到这一点,就像这样:Cart.getCart(displayCart)。请注意 displayCart() 是一个回调函数,由服务器返回的 Cart 响应数据调用。

  如果 Cart 已经在会话中,那么creator 会检索它并调用它的 getCart() 方法。如果会话中没有 Cart,那么 creator 会实例化一个新的,把它放在会话中,并调用 getCart() 方法。

  清单 7 显示了 addToCartButtonHandler() 函数的实现,当点击商品的 Add to Cart 按钮时会调用这个函数:

  清单 7. addToCartButtonHandler() 实现

/*
 * Handles a click on an Item's "Add to Cart" button
 */
function addToCartButtonHandler() {

  // 'this' is the button that was clicked.
  // Obtain the item ID that was set on it, and
  // add to the cart.
  Cart.addItemToCart(this.itemId,displayCart);
}

由 DWR 负责所有通信,所以客户上的添加到购物车行为就是一个函数。清单 8 显示了这个示例的最后一部分 —— displayCart() 回调的实现,它用 Cart 的状态更新用户界面:

  清单 8. displayCart() 实现

/*
 * Displays the contents of the user's shopping cart
 */
function displayCart(cart) {

  // Clear existing content of cart UI
  var contentsUL = $("contents");
  contentsUL.innerHTML="";

  // Loop over cart items
  for (var item in cart.simpleContents) {

    // Add a list element with the name and quantity of item
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(
                    cart.simpleContents[item] + " x " + item
                  ));
    contentsUL.appendChild(li);
  }

  // Update cart total
  var totalSpan = $("totalprice");
  totalSpan.innerHTML = cart.formattedTotalPrice;
}

  在这里重要的是要记住,simpleContents 是一个把 String 映射到数字的 JavaScript 数组。每个字符串都是一个商品的名称,关联数组中的对应数字就是购物车中该商品的数量。所以表达式 cart.simpleContents[item] + " x " + item 可能就会计算出 “2 x Oolong 128MB CF Card” 这样的结果。

  DWR 商店应用程序

  图 3 显示了这个基于 DWR 的 Ajax 应用程序的使用情况:显示了通过搜索检索到的商品,并在右侧显示用户的购物车:

  图 3. 基于 DWR 的 Ajax 商店应用程序的使用情况

  DWR 的利弊

  现在可以看出用 DWR 实现由 Java 支持的 Ajax 应用程序有多么容易了。虽然示例场景很简单,我实现用例的手段也尽可能少,但是不应因此而低估 DWR 引擎相对于自己设计 Ajax 应用程序可以节约的工作量。在前一篇文章中,我介绍了手工设计 Ajax 请求和响应、把 Java 对象图转化成 JSON 表示的全部步骤,在这篇文章中,DWR 替我做了所有这些工作。我只编写了不到 50 行 JavaScript 就实现了客户机,而在服务器端,我需要做的所有工作就是给常规的 JavaBean 加上一些额外方法。

  当然,每种技术都有它的不足。同任何 RPC 机制一样,在 DWR 中,可能很容易忘记对于远程对象进行的每个调用都要比本地函数调用昂贵得多。DWR 在隐藏 Ajax 的机械性方面做得很好,但是重要的是要记住网络并不是透明的 —— 进行 DWR 调用会有延迟,所以应用程序的架构应当让远程方法的粒度比较粗。正是为了这个目的,addItemToCart() 才返回 Cart 本身。虽然让 addItemToCart() 作为一个 void 方法可能更自然,但是这样的话对它的每个 DWR 调用后面都必须跟着一个 getCart() 调用以检索修改后的 Cart 状态。

  对于延迟,DWR 在调用的批处理中有自己的解决方案。如果不能为应用程序提供适当粗粒度的 Ajax 接口,那么只要有可能把多个远程调用组合到一个 HTTP 请求中,就请使用调用批处理。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章