DWR详解(二)——反向AJAX
上一篇文章(DWR详解一)提到DWR允许javascript访问服务器端的Java方法,这使得AJAX使用起来会比较容易,而在DWR2.0里面添加了一个非常强大的功能——反向AJAX,也就是说,服务器端的Java方法可以取得浏览器端的Web上下文,并可以调用javascript的方法,将服务器端的数据异步地传输给浏览器。本文将通过一个demo展示这种特性。这个demo实现了类似股票交易系统中实时更新数据的功能,事实上是通过发布-订阅模式去实现的。也就是说,客户端订阅一个主题,服务器端通过一个线程向订阅这个主题的浏览器定时、异步地发送数据,从而实现了这种实时更新的功能。工程代码请点击这里
下载:
reverseAjaxDemo
我们知道,客户端浏览器可以随时连接到web服务器,并向服务器请求资源,而服务器却没有这种能力,它不能主动地于客户端浏览器建立连接,并主动地将数据发送给浏览器。DWR支持3种从服务器端发送数据给客户端的方式: 1、轮询。客户端在每个时间周期内向服务器发送请求,看看服务器端有没有数据更新,如果有,就向服务器请求数据。 2、Comet:基于HTTP长连接的服务器推动方式。客户端向服务器发送请求后,服务器将数据通过response发送给客户端,但并不会将此response关闭,而是一直通过response将最新的数据发送给客户端浏览器,直到客户端浏览器关闭。 3、PiggyBack(回传)。服务器端将最新的数据排成队列,然后等待客户端下一次请求,接收到请求后就将等待更新的数据发给客户端。 这3种方式各有优劣,而DWR可以同时支持轮询和Comet。 首先,我们要让DWR程序支持反向AJAX。只需要在web.xml中DWRServlet里添加一个初始化参数: <servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
...
</servlet>
另外,这个demo使用了TIBCO General Interface(GI)的AJAX框架,因此需要引入JSX这个组件库以及在gidemo目录下在config.xml和appCanvas.xml定义需要使用的组件(主要是用到Matrix数据表格这个组件),关于TIBCO GI,请参考http://www.tibco.com/devnet/index.html 这个demo的核心之处在于服务器端的发布者——Publisher.java,在这个类里面,首先通过org.directwebremoting.WebContext来获得访问这个应用的Web上下文: WebContext webContext = WebContextFactory.get(); webContext.getScriptSessionsByPage(""); 这里主要通过WebContext类获得DWR应用的WEB上下文,用ServletContext获得DWRServlet的上下文,以及通过WEB上下文获取访问本应用的客户端浏览器的ScriptSession。通过ScriptSession,可以在服务器端向客户端浏览器发出执行js方法的指令,并把服务器端数据传送给js方法,具体的用法如下: Collection sessions = serverContext.getScriptSessionsByPage("/reverseAjaxDemo/index.html"); 这段代码首先通过getScriptSessionsByPage方法获得所有访问/reverseAjaxDemo/index.html这个资源的客户端浏览器的ScriptSession,并为这些session建立代理(ScriptProxy),通过这个代理,让客户端执行OpenAjax.publish的js方法(见OpenAjax.js)。其中addFunctionCall就是向客户端发送执行js方法的服务器端方法,第一个参数是js方法的签名,后面的都是js方法的参数。其中"gidemo"是服务器端发布的主题(topic),"coporation"是要发布的变量,而corp则是要发布的即时数据。corp这个对象是随机生成的(见Corporation和Corporations类),Publish.java这个类启动了一个线程(worker),这个线程不断地生成corporation的数据,并发布给客户端。 以下是html页面的核心部分的代码: <div style="width:100%; height:280px;" id="gidemo"> 这一块代码主要是使用了GI的matrix组件,该组件可以动态加载数据。另外,页面引入了index.js,里面有两个个主要方法:
giLoaded方法通过OpenAjax.subscribe方法订阅主题为"gidemo"的数据(这些数据由服务器端的Java方法进行发布)。其中objectPublished是一个回调方法,表示取得数据后页面的改变。该回调方法非常简单,只是将matrix组件中发生变化的数据改变一下颜色,实现了实时提醒数据更新的功能。 另外,服务器端还有一个监听器PublisherServletContextListener,这是为了在适当的时候关闭发布者的线程。这个监听器要结合其他两个DWR的监听器使用,只需在web.xml里面声明就行了: <listener> 最后,看一下dwr的映射关系dwr.xml: <dwr> 注意红色部分的配置,dwr允许将自定义的Java类型与js对象进行相互转换,但要声明转换器。 以下是程序运行的结果:
这个例子比较复杂,旨在让大家对反向AJAX的原理有所了解。下一篇文章开始,将用一些简单的例子来说明DWR反向AJAX的用法。 参考资料: http://getahead.org/dwr/reverse-ajax (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |