上一篇文章(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();
ServletContext servletContext = webContext.getServletContext();
serverContext = ServerContextFactory.get(servletContext);
webContext.getScriptSessionsByPage("");
这里主要通过WebContext类获得DWR应用的WEB上下文,用ServletContext获得DWRServlet的上下文,以及通过WEB上下文获取访问本应用的客户端浏览器的ScriptSession。通过ScriptSession,可以在服务器端向客户端浏览器发出执行js方法的指令,并把服务器端数据传送给js方法,具体的用法如下:
Collection sessions = serverContext.getScriptSessionsByPage("/reverseAjaxDemo/index.html");
ScriptProxy proxy = new ScriptProxy(sessions);
Corporation corp = corporations.getNextChangedCorporation();
proxy.addFunctionCall("OpenAjax.publish", "gidemo", "corporation", corp);
这段代码首先通过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">
<script. type="text/javascript"
src="JSX/js/JSX30.js"
jsxapppath="gidemo"
jsxlt="true"> </script>
</div>
这一块代码主要是使用了GI的matrix组件,该组件可以动态加载数据。另外,页面引入了index.js,里面有两个个主要方法:
function giLoaded() {
OpenAjax.subscribe("gidemo", "corporation", objectPublished);
dwr.engine.setActiveReverseAjax(true);
}
function objectPublished(prefix, name, handlerData, corporation) {
var matrix = giApp.getJSXByName("matrix");
var inserted = matrix.getRecordNode(corporation.jsxid);
matrix.insertRecord(corporation, null, inserted == null);
// There are many ways to get a table to repaint.
// One easy way is to ask it to repaint:
// matrix.repaintData();
// But we are going for a fancy option that does highlighting
for (var property in corporation) {
if (property != "jsxid") {
var x = matrix.getContentElement(corporation.jsxid, property);
if (ox) {
var current = ox.innerHTML;
if (current != "" + corporation[property]) {
ox.style.backgroundColor = "#FDE4EB";
var callback = function(ele) {
return function() { ele.style.backgroundColor = "#FFFFFF"; };
}(ox);
setTimeout(callback, 1000);
ox.innerHTML = corporation[property];
}
}
}
}
}
giLoaded方法通过OpenAjax.subscribe方法订阅主题为"gidemo"的数据(这些数据由服务器端的Java方法进行发布)。其中objectPublished是一个回调方法,表示取得数据后页面的改变。该回调方法非常简单,只是将matrix组件中发生变化的数据改变一下颜色,实现了实时提醒数据更新的功能。
另外,服务器端还有一个监听器PublisherServletContextListener,这是为了在适当的时候关闭发布者的线程。这个监听器要结合其他两个DWR的监听器使用,只需在web.xml里面声明就行了:
<listener>
<listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener</listener-class>
</listener>
<listener>
<listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextListener</listener-class>
</listener>
<listener>
<listener-class>gidemo.PublisherServletContextListener</listener-class>
</listener>
最后,看一下dwr的映射关系dwr.xml:
<dwr>
<allow>
<create creator="new" javascript="JDate">
<param name="class" value="java.util.Date"/>
</create>
<create creator="new" javascript="Publisher" scope="application">
<param name="class" value="gidemo.Publisher"/>
</create>
<convert converter="bean" match="gidemo.Corporation"/>
<!-- this is a bad idea for live, but can be useful in testing -->
<convert converter="exception" match="java.lang.Exception"/>
<convert converter="bean" match="java.lang.StackTraceElement"/>
</allow>
</dwr>
注意红色部分的配置,dwr允许将自定义的Java类型与js对象进行相互转换,但要声明转换器。
以下是程序运行的结果:
这个例子比较复杂,旨在让大家对反向AJAX的原理有所了解。下一篇文章开始,将用一些简单的例子来说明DWR反向AJAX的用法。
参考资料:
http://getahead.org/dwr/reverse-ajax
相关推荐
【反向Ajax聊天实例详解】 在Web开发中,Ajax(Asynchronous JavaScript and XML)技术的出现极大地提升了用户体验,使得页面无需刷新即可与服务器进行数据交互。而“反向Ajax”(Reverse Ajax)则是Ajax的一种扩展...
DWR (Direct Web Remoting) 是一个开源Java库,它允许在浏览器和服务器之间进行实时的、异步的通信,即所谓的反向Ajax技术。在"DWR 3.0反向实例"中,我们将深入探讨这个版本的新特性、配置过程以及如何通过一个简单...
**Ajax DWR详解** Ajax(Asynchronous JavaScript and XML)是一种在无需刷新整个网页的情况下更新部分网页的技术,极大地提升了用户体验。而Direct Web Remoting (DWR) 是一个开源Java库,它使得JavaScript和Java...
**Ajax与DWR详解** Ajax(Asynchronous JavaScript and XML)是一种在无需刷新整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,大大提升了用户体验。Ajax的...
#### 二、DWR XML配置详解 除了`web.xml`配置外,还需要定义DWR的XML配置文件,该文件定义了服务器端对象的访问规则和权限控制: ```xml <dwr> </dwr> ``` 这段XML配置指定了一个名为`Demo`的客户端...
DWR的核心是反向Ajax(Reverse AJAX),即服务器可以主动向客户端发送数据,而不仅仅局限于客户端发起请求。DWR通过提供一系列API和配置,使得在JavaScript中调用服务器端的Java方法变得简单。主要概念包括: - **...
DWR(Direct Web Remoting)是一种JavaScript库,它允许在Web浏览器和服务器之间进行实时、双向通信,即所谓的"反向Ajax"或"Comet"技术。DWR使得Web应用程序能够像桌面应用一样更新页面,而无需用户手动刷新。在这个...
1. **反向Ajax(Reverse Ajax)**:DWR的核心功能之一是实现反向Ajax,即服务器可以主动向客户端推送数据,而不仅仅是响应客户端的请求。这使得Web应用能够实现类似桌面应用的即时更新效果。 2. **安全机制**:DWR...
总的来说,DWR技术通过反向Ajax提供了一种强大的实时Web通信手段,使得服务器能够主动向客户端推送数据,这对于构建实时性要求高的应用,如在线聊天、股票监控、即时消息等,具有极大的价值。通过合理配置和管理`...
- **Reverse Ajax**:DWR的反向Ajax功能,允许服务器主动向客户端发送数据。 - **AutoComplete**:自动完成功能,用于在表单输入框中提供动态下拉建议。 - **Echo**:实现实时更新,例如股票价格或聊天室消息。 ...
这种双向交互方式通常被称为反向Ajax(Reverse Ajax),能够极大地提高Web应用程序的响应速度和用户体验。 DWR的核心价值在于其强大的数据交换能力和易用性。它支持几乎所有的数据结构在Java和JavaScript之间进行...
3. **反向Ajax**:当服务器有新数据时,DWR可以通过反向Ajax技术将数据推送到客户端。这是长连接的关键,它使得服务器能主动向客户端推送信息,而不仅仅是响应客户端的请求。 4. **安全机制**:DWR提供了一套安全...
DWR的核心在于它的反向AJAX(Reverse AJAX)机制。传统的AJAX通常由客户端发起请求,服务器响应数据。而DWR则允许服务器主动向客户端推送数据,这种机制使得Web应用能实时更新数据,提高了交互性。 ### 2. DWR的...
1. **反向Ajax(Reverse Ajax)**:DWR允许服务器主动向客户端发送数据,打破了传统的Web应用中由客户端发起请求的模式。 2. **自动类型转换**:DWR可以自动将Java对象转换为JavaScript对象,并反之亦然,大大简化了...
2. **Reverse Ajax(反向Ajax)**:DWR利用了反向Ajax的概念,即服务器可以主动向客户端发送数据,而不仅仅是响应客户端的请求。这使得应用能够实现实时更新。 3. **安全控制**:DWR提供了多种安全机制,包括CSRF...
是否激活反向Ajax <param-name>activeReverseAjaxEnabled <param-value>true 在WEB启动时是否创建范围为application的creator <param-name>initApplicationScopeCreatorsAtStartup <param-value>true ...
这篇教程将详细介绍如何将这三个框架与Direct Web Remoting (DWR)进行整合,以及如何根据Pojo(Plain Old Java Object)对象反向生成数据库表。 **SSH框架详解:** 1. **Spring**:Spring 是一个全面的后端应用框架...
6. **DWR的反向Ajax调用**:在`showSecondSort()`函数中,DWR的`DWRUtil`工具类用于操作DOM,首先清除小类下拉框的所有选项,然后初始化并添加新的选项。这个方法接收从服务器返回的数据,这些数据是DWR方法`...
- `activeReverseAjaxEnabled`:是否启用主动反向AJAX功能,默认为`true`。 - `initApplicationScopeCreatorsAtStartup`:启动时是否初始化应用范围创建者,默认为`true`。 - `maxWaitAfterWrite`:最大等待时间...