DWR知识介绍

 

DWR介紹

  DWR是一个源的类库,可以帮助开发员开发包含AJAX的网站.它可以允浏览器里的代使用运行在WEB器上的JAVA函数,就像它就在浏览器里一.它包含两个主要的部分:JavaScriptWEB器上一个遵循了AJAXServlet(用程序)取数据.另外一方面一个JavaScript可以帮助网站开发员轻松地利用取的数据来动态的内容.

  DWR采取了一个AJAX的新方法来动态生成基于JAVAJavaScript.这样WEB开发就可以在JavaScript里使用Java就像它浏览器的本地代(端代);但是Java运行在WEB器端而且可以自由访问WEB 器的.出于安全的理由,WEB开发者必适当地配置哪些Java可以安全的被外部使用.

  这个从JAVAJavaScript程功能方法DWR的用户带来非常像传统RPC机制,就像RMI或者SOAP,而且有运行在WEB上但是不需要浏览器插件的好.

  DWR认为浏览/WEB协议是重要的,而更于保证编程界面的简单自然.此最大的挑就是把AJAX的异特性和正常JAVA方法用的同特性相.在异模式下,果数据在用之后的一段时间之后才可以访问.DWR解决了问题,WEB开发使用一个特殊的方法参数来指定一个函数,以便在数据返回后来回此函数.

 

DWR 是什

  从最简单的角度来DWR 是一个引擎,可以把服器端 Java 象的方法公开给 JavaScript 。使用 DWR 可以有效地从用程序代中把 Ajax 的全部-消除掉。意味着客端代再也不需要直接 XMLHttpRequest 象或者服器的响。不再需要象的序列化代或者使用第三方工具才能把 XML。甚至不再需要 servlet Ajax 整成 Java 象的用。

  DWR 是作 Web 用程序中的 servlet 部署的。把它看作一个黑盒子, servlet 有两个主要作用:首先,于公DWR 动态地生成包含在 Web 面中的 JavaScript。生成的 JavaScript 包含存根函数,代表 Java 上的对应方法并在幕后 XMLHttpRequest求被 DWR这时它的第二个作用就是把求翻成服器端 Java 象上的方法用并把方法的返回放在 servlet 送回客端,编码 JavaScriptDWR 提供了帮助行常的用界面任 JavaScript 工具函数。

于示例

  在更详细地解 DWR 之前,我要介一个简单的示例景。我将采用一个基于在线商店的最小模型,次包含一个基本的品表示、一个可以包含品商品的用户购以及一个从数据存储查询产品的数据访问对象(DAO)。Item 与前一篇文章中使用的一,但是不再实现任何手工序列化方法。 1 明了简单置:

1. CartCatalogDAO Item 类图

景中,我将演示两个非常简单的用例。第一,用可以在目行文本搜索并看匹配的商品。第二,用可以添加商品到中并中商品的价。

实现

  DWR 用程序的起点是写服器端象模型。在个示例中,我从 DAO 始,用它提供对产品目数据存的搜索功能。CatalogDAO.java 是一个简单的无状,有一个无参数的构造函数。清 1 示了我想要公开给 Ajax Java 方法的名:

1. DWR CatalogDAO 方法

/**

 * Returns a list of items in the catalog that have

 *  names or descriptions matching the search expression

 * @param expression Text to search for in item names

 *  and descriptions

 * @return list of all matching items

 */

public List<Item> findItems(String expression);

/**

 * Returns the Item corresponding to a given Item ID

 * @param id The ID code of the item

 * @return the matching Item

 */

public Item getItem(String id);

  接下来,我需要配置 DWR,告 Ajax 户应当能构建 CatalogDAO 些方法。我在清 2 所示的 dwr.xml 配置文件中做些事:

2. CatalogDAO 方法的配置

<!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>

  </allow>

</dwr>

  dwr.xml 文档的根元素是 dwr。在个元素内是 allow 元素,它指定 DWR 程的allow 的两个子元素是 create convert

create 元素

  create 元素告 DWR 当公开给 Ajax 求的服器端,并定 DWR 当如何得要程的例。里的 creator 属性被为值 new意味着 DWR 的默构造函数来例。其他的可能有:通段用 Bean 脚本框架(Bean Scripting FrameworkBSF例,或者通 IOC 容器 Spring 行集成来例。默情况下,到 DWR Ajax 求会 creator例化的面范内,因此求完成之后就不再可用。在无状 CatalogDAO 情况下,这样很好。

  create javascript 属性指定从 JavaScript 码访问对使用的名称。嵌套在 create 元素内的 param 元素指定 creator 建的 Java 。最后,include 元素指定当公的方法的名称。式地明要公的方法是避免偶然许访问有害功能的良好 —— 如果漏了个元素,的所有方法都会公开给远用。反来,可以用 exclude 元素指定那些想防止被访问的方法。

convert 元素

  creator 负责用于 Web 程的的方法,convertor 则负责这些方法的参数和返回型。convert 元素的作用是告 DWR 在服器端 Java 象表示和序列化的 JavaScript 如何转换数据型。

  DWR 地在 Java JavaScript 表示之间调简单数据型。型包括 Java 原生型和它各自的表示, StringDate、数和集合型。DWR 也能把 JavaBean 转换 JavaScript 表示,但是出于安全性的原因,做件事要求式的配置。

   2 中的 convert 元素告 DWR 用自己基于反射的 bean 转换 CatalogDAO 的公方法返回的 Item,并指定序列化中当包含 Item 的哪个成。成的指定采用 JavaBean 命名范,所以 DWR 对应 get 方法。在个示例中,我去掉了数字的 price 字段,而是包含了 formattedPrice 字段,它采用货币格式示。

  在,我准 dwr.xml 部署到 Web 用程序的 WEB-INF ,在那里 DWR servlet 取它。但是,在继续之前,确保件事都按照希望的那运行是个好主意。

测试部署

  如果 DWRServlet web.xml init-param debug true,那就启用了 DWR 非常有帮助的测试模式。航到 /{your-web-app}/dwr/ 会把 DWR 配置的要程的列表示出来。在其中点,会入指定的状屏幕。CatalogDAO DWR 测试页 2 所示。除了提供粘 Web 面的 script 标记(指向 DWR 为类生成的 JavaScript)之外,个屏幕提供了的方法列表。个列表包括从的超类继承的方法,但是只有在 dwr.xml 式地指定为远程的才标记为访问

2. CatalogDAO DWR 测试页

  可以在可访问的方法旁的文本框中入参数并点 Execute 钮调用方法。服器的响将在警告框中用 JSON 示出来,如果是简单值,就会内在方法旁直接示。测试页非常有用。它许检查了哪个和方法用于程,可以测试每个方法是否像期的那工作。

  如果对远程方法的工作感到意,就可以用 DWR 生成的 JavaScript 存根从客端代码调用服器端象。

  远 Java 象方法和对应 JavaScript 存根函数之的映射很简单。通用的形式是 JavaScriptName.methodName(methodParams ..., callBack),其中 JavaScriptName creator javascript 属性指定的名称,methodParams 代表 Java 方法的 n 个参数,callback 是要用 Java 方法的返回值调用的 JavaScript 函数。如果熟悉 Ajax,可以看出个回机制是 XMLHttpRequest 性的常用方式。

  在示例景中,我用清 3 中的 JavaScript 函数行搜索,并用搜索果更新用界面。个清单还使用来自 DWR util.js 的便捷函数。要特别说明的是名 $() JavaScript 函数,可以把它当作 document.getElementById() 的加速版。入它当然更容易。如果您使用 JavaScript 原型当熟悉个函数。

3. 从客程的 findItems()

/*

 * Handles submission of the search form

 */

function searchFormSubmitHandler() {

  // Obtain the search expression from the search field

  var searchexp = $("searchbox").value;

  // Call remoted DAO method, and specify callback function

  catalog.findItems(searchexp, displayItems);

  // Return false to suppress form submission

  return false;

}

      

/*

 * Displays a list of catalog items

 */

function displayItems(items) {

  // Remove the currently displayed search results

  DWRUtil.removeAllRows("items");

  if (items.length == 0) {

    alert("No matching products found");

    $("catalog").style.visibility = "hidden";

  } else {

    DWRUtil.addRows("items",items,cellFunctions);

    $("catalog").style.visibility = "visible";

  }

}

  在上面的 searchFormSubmitHandler() 函数中,我趣的代当然是 catalog.findItems(searchexp, displayItems);一行代就是通 DWR servlet XMLHttpRequest 并用象的响应调 displayItems() 函数所需要的全部内容。

  displayItems() 本身是由一个 Item 表示用的。个数组传递给 DWRUtil.addRows() 便捷函数,同时还有要填充的表的 ID 和一个函数数。表中行有多少元格,个数中就有多少个函数。按照序使用来自数 Item 逐个个函数,并用返回的内容填充对应元格。

  个示例中,我想商品表中的一行都示商品的名称、明和价格,并在最后一列示商品的 Add to Cart 。清 4 示了实现这一功能的元格函数数

4. 填充商品表的元格函数数

/*

 * Array of functions to populate a row of the items table

 * using DWRUtil's addRows function

 */

var cellFunctions = [

  function(item) { return item.name; },

  function(item) { return item.description; },

  function(item) { return item.formattedPrice; },

  function(item) {

    var btn = document.createElement("button");

    btn.innerHTML = "Add to cart";

    btn.itemId = item.id;

    btn.onclick = addToCartButtonHandler;

    return btn;

  }

];

  前三个函数只是返回 dwr.xml Item convertor 包含的字段内容。最后一个函数建一个按,把 Item ID 赋给它,并指定在点钮时应用名 addToCartButtonHandler 的函数。个函数是第二个用例的入口点:向中添加 Item

实现购

  户购 Java 表示基于 Map。当 Item 添加到Item 本身作为键被插入 Map Map 对应是一个 Integer,代表中指定 Item 的数量。所以 Cart.java 有一个字段 contents,声明 Map<Item,Integer>

  使用复杂类型作哈希键给 DWR 来一个问题 —— JavaScript 中,数量的。所以,DWR 无法转换 contents Map。但是,界面来,用需要看的只是个商品的名称和数量。所以我向 Cart 添加了一个名 getSimpleContents() 的方法,它接受 contents Map 并根据它构建一个化的 Map<String,Integer>,只代表 Item 的名称和数量。个用字符串作为键 map 表示可以由 DWR 转换转换 JavaScript

  户对 Cart 趣的其他字段是 totalPrice,它代表中所有商品的金额汇总。使用 Item,我提供了一个合成的成叫作 formattedTotalPrice,它是金额汇总的格式化好的 String 表示。

DWR 的安全性

DWR 设计时就考了安全性。使用 dwr.xml 明确地列出那些想做理的和方法,可以避免意外地把那些可能被意利用的功能公出去。除此之外,使用调试测试模式,可以容易地审计所有公 Web 上的和方法。

DWR 也支持基于角色的安全性。通 bean creator 配置,可以指定用户访问特定 bean 所必属于的 J2EE 角色。通部署多个 URL 受保 DWRServlet 例,例都有自己的 dwr.xml 配置文件,也可以提供有不同程功能的用集。

转换购

  为了不码对 Cart 做两个用(一个得内容,一个价),我想把些数据一次全都发给了做到一点,我添加了一个看起来有点儿怪的方法,如清 5 所示:

5. Cart.getCart() 方法

/**

 * Returns the cart itself - for DWR

 * @return the cart

 */

public Cart getCart() {

  return this;

}

  个方法在普通的 Java 中可能完全是多余的(因个方法,已 Cart 的引用),但它允 DWR 户让 Cart 把自己序列化成 JavaScript

 

  除了 getCart(),需要程化的另一个方法是 addItemToCart()个方法接受目 Item ID String 表示,把个商品添加到 Cart 中并更新价。方法返回 Cart这样在一个操作中就能更新 Cart 的内容并接收的新状

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 convertorcreate 元素指定当把 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 求中,就使用用批理。

用批

DWR 中,可以在一个 HTTP 求中向服送多个用。 DWREngine.beginBatch() DWR 不要直接分派后用,而是把它们组合到一个批求中。DWREngine.endBatch() 把批送到服器。用在服器端行,然后 JavaScript

理在两方面有助于降低延:第一,避免了为每 XMLHttpRequest 象并建立相 HTTP 接的开销。第二,在生产环境中,Web 不必多的并 HTTP 求,改了响应时间

分离的问题

  实质上看,DWR 在客端和服器端代码间形成了密的耦合,多含:首先,程方法 API 化需要在 DWR 存根用的 JavaScript 上反映出来。第二(也是最明的),这种耦合会造成端的考入服器端代。例如,因不是所有 Java 型都能化成 JavaScript,所以有有必要 Java 象添加外方法,好它能更容易地程化。在示例景中,我通 getSimpleContents() 方法添加到 Cart 来解决问题。我添加了 getCart() 方法,它在 DWR 景中是有用的,但在其他景中完全是多余的。由于象粗粒度 API 的需要以及把某些 Java 化成 JavaScript 问题,所以可以看到 JavaBean 会被那些只 Ajax 有用的方法“染”。

  为了克服问题,可以使用包装器外的特定于 DWR 的方法添加到普通 JavaBean意味着 JavaBean Java 可能看不到与程相关联外的毛病,而且也允许给远程方法提供更友好的名称 —— 例如用 getPrice() 代替 getFormattedPrice() 4 示的 RemoteCart 类对 Cart 行了包装,添加了外的 DWR 功能:

4. RemoteCart 为远程功能 Cart 做了包装

  最后,需要住:DWR Ajax 用是异的,所以不要期望它会按照分派的序返回。在示例代中我忽略了个小问题,但是在个系列的第一篇文章中,我演示了如何时间戳,以此作数据到达序的一种简单手段。

  正如所看到的,DWR 提供了西 —— 它允迅速而简单建到服器端域象的 Ajax 接口,而不需要写任何 servlet 象序列化代或客 XMLHttpRequest 。使用 DWR 部署到 Web 用程序极为简单,而且 DWR 的安全性特性可以与 J2EE 基于角色的验证集成。但是 DWR 并不是于任何一种应用程序架构都适合,所以在设计象的 API 需要做些考

  如果想学 DWR Ajax 的利弊的更多内容,最好的方式就是下践。DWR 多我没有介的特性, 文章源代 是把 DWR 投入使用的一个良好起点。 参考料,学习关 AjaxDWR 和相的更多内容。

  这个系列中要指出的最重要的一点是: Ajax 用程序,没有包治百病的解决方案。Ajax 是一个快速展的域,不断有新技。在个系列的三篇文章中,我的重点在于始在 Ajax 用程序的 Web 中利用 Java —— 不管是选择基于 XMLHttpRequest 象序列化框架的技选择 DWR 这样的更高抽象。在后个月中留意面向 Java 开发 Ajax 的文章。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值