DWR详解——会变魔术的Javasript(一)

Javascript在AJAX(Asyncronize Javascript. And XML)技术中扮演者非常重要的角色,但是对于Java程序员来说,编写Javascript并不是一件容易的事情,而要做到Javascript与服务器端的Java对象交互更是困难。DWR(Direct Web Remoting)帮助我们解决了这个问题,让Javascript能够非常简便地与Java对象进行交互,让程序员感觉在Javascript中调用一个方法就像调用一个Java对象里的方法一样。这种交互是非常重要的,编写最原始的AJAX程序至少需要经过7个步骤才能通过一个Servelet取得服务器端的数据回显给用户,而DWR让我们只需一步即能达到这种效果。以下是一个简单的例子,我们需要通过判断用户输入的字符从服务器中取出以这些字符开头的所有字符串。其中服务器端Java对象最核心的方法是通过判断前缀(prefix)取出相应的字符串数组:

public List getData(String prefix) {
        return DemoDataProvider.getDemoData(prefix);
}

通过DWR,我们可以在Javascript“直接”调用这个属于服务器端的远程方法:

Demo.getData(input, function(data) {
      dwr.util.setValue("result", data);
});

神奇吧?让我们以这个为例子逐步地了解DWR吧!

DWR最新的稳定版本是2.0,在本例子中,使用的是DWR2.03,DWR的库可以在

https://dwr.dev.java.net/files/documents/2427/87007/dwr.jar

下载,DWR2.0需要commons-logging和log4j库,所以建立DWR工程需要引入dwr.jar及这两个包。

    首先,DWR是用DwrServlet作为中心控制器的,所以建立Web application,引入相关的jar包后首先要做的是在web.xml中声明这个Servlet。在web.xml中加入以下servlet声明:

<servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
   
<servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

因此,访问dwr应用的url是http://domain/yourAppName/dwr/...。

另外,这个工程需要引入一个数据提供的Java Application,在实际应用中,我们可以从数据库中取得这些数据,为了方便起见,这里采用一个简单的数据提供程序Ajax_DemoData(provided by Michael Li),在建立Netbeans Web应用工程后,点击工程右键选择属性-库,选择“添加项目”,将该数据提供项目添加进去。

好,现在让我们了解DWR应用的页面是如何编写的,以下是页面代码(index.html):

<html>
    <head>
        <meta. http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
       <script. type='text/javascript' src='dwr/interface/Demo.js'></script>
        <script. type='text/javascript' src='dwr/engine.js'></script>
        <script. type='text/javascript' src='dwr/util.js'></script> 
      
        <script. type='text/javascript'>
           function getDemoData() {
                var input = dwr.util.getValue("prefix");
                Demo.getData(input, function(data) {
                        dwr.util.setValue("result", data);
                });
            }

        </script>
    </head>
    <body>
        <h2>DWR Demo</h2>
        <input id="prefix" type=text nkeyup='getDemoData()'/>
        <br>
        <span id="result"></span>
    </body>
</html>

    注意蓝色部分的代码,第一行引入了Demo.js这个javascript,事实上,Demo是服务器端Java对象在客户端的一个映射,我们不需要自己创建这个js,DWR会自动为我们生成这个映射,他的魔力就在这里,DWR里有一套API可以将一个Java对象转换为一个客户端的js,所以我们就可以在客户端去调用在服务器端的远程方法了。具体的映射方法会在后续详述。engine.js是DWR中将js的方法与Java对象中的方法动态交互的引擎,因此每个DWR都要引入这个js文件。这个js提供了一些与服务器异步交互、处理异常以及处理回调方法等功能。util.js封装了很多原始的javascript方法,例如,我们可以用getValue(elementId)来代替document.getElementById(elementId)的方法。

    html正文(body)部分,我们通过触发文本输入框的onkeyup事件进行处理,在黑体部分,我们首先通过dwr.util.getValue方法获取用户输入的字符串,然后将取得的值传递给getData方法。前面提到,js里面的getData方法会去调用服务器端的getData方法,以下是Java代码:

package datasource;

import java.util.List;
import my.demo.data.DemoDataProvider;

public class DataProvider {
   
    public List getData(String prefix){
        return DemoDataProvider.getDemoData(prefix);
    }

}

我们回到js方法
Demo.getData(input, function(data) {
    dwr.util.setValue("result", data);
});
第一个参数input会把客户端的值传到Java对象的方法列表中(可以传递多个参数),第二个参数事实上是一个回调(callBack)方法,回调方法从Java方法中获取返回值data并将data回显给客户端浏览器。事实上,详细的调用方式应该是这样的:

function getDemoData() {
   var input = dwr.util.getValue("prefix");
                
   var callMetaData = {
      callback:callbackFunction, //声明回调方法
      args: input // 要传到服务器端的客户端参数
   };
                
   Demo.getData(input, callMetaData);
                
   function callbackFunction(dataFromServer) {
       dwr.util.setValue("result", dataFromServer);
   };
}

其中,dwr.util.setValue将服务器返回的数据传递给页面中id为"result"的控件,也就是<span id="result"></span>。

好了,客户端和服务器端的代码都已完成,接下来,需要定义服务器端到客户端之间的映射。在WEB-INF路径下创建一个dwr.xml文件,以下是代码:

<dwr>
  <allow>
    <create creator="new" javascript="JDate">
      <param name="class" value="java.util.Date"/>
    </create>
    <create creator="new" javascript="Demo">
      <param name="class" value="datasource.DataProvider"/>
    </create>
  </allow>
</dwr>

相信现在你已经清楚为什么我们可以在客户端的js方法中通过Demo来调用服务器端DataProvider里面的方法了。事实上,我们在js中使用Demo时,DWR会帮助我们构造一个DataProvider对象,并调用这个对象里面的方法,并对返回的数据进行回调处理。注意,这个过程是异步的,也就是说,在与服务器进行交互时,不需要进行页面的刷新。

生成工程,并运行index.html,在输入框中输入例如字符J,字符P,你就可以看到结果了:

 

参考资料:

Michael的博客:http://developers.sun.com.cn/blog/sunblade/category/Web+2.0

DWR官方网站:http://getahead.org/dwr/

Written by Yuanxin-Li

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值