DWR介绍
What is DWR?:
1.在服务器上运行的Servlet来处理请求并把结果返回浏览器。
2.运行在浏览器上的Javascript,可以发送请求,并动态 改变页面。DWR会根据你的Java类动态的生成Javascript代码。这些代码魔力是让你感觉整个Ajax调用都是在浏览器上发生的,但事实上是服务器执行了这些代码,DWR负责数据的传递和转换。
3.这种Java和Javascript之间的远程调用会让DWR用户感觉像是曾经习惯使用的RMI或SOAP的RPC机制。而且这一过程还不需要额外的浏览器插件。
4.Java是同步的,而Ajax是异步的。所以当你调用一个远程方法时,你要给DWR一个回调函数,当数据从网络上回来时,DWR会调用这个函数。
DWR的作用:
1.有效地从应用程序代码中把 Ajax 的全部请求-响应循环消除掉。
2.客户端代码再也不需要直接处理XMLHttpRequest 对象或者服务器的响应。
3.不再需要编写对象的序列化代码或者使用第三方工具才能把对象变成 XML。
4.不再需要编写 servlet 代码把 Ajax 请求调整成对 Java 域对象的调用
DWR原理
DWR是作为Web应用的一个Servlet进行部 署的,是一个黑盒子中的servlet。
对于公共有的每个类,DWR 动态地生成包含在 Web 页面中的 JavaScript。生成的JavaScript 包含存根函数,代表 Java 类上的 对应方法并在幕后执行XMLHttpRequest。这些请求被发送给DWR。
把请求翻译成服务器端 Java 对象上的方法调用并把方法的返回值放在servlet 响应中发送回客户端,编码成 JavaScript。
写几个例子: 部署在TOMCAT上,下载附件中的工程,直接可以再TOMCat上跑
test.jsp
<%@ page language="java" pageEncoding="GBK"%> <html> <head> <title>DWR - Test Home</title> <script type='text/javascript' src='dwr/interface/MyTest.js'></script> <script type='text/javascript' src='dwr/engine.js'></script> <script type='text/javascript' src='dwr/util.js'></script> <script language="javascript"> var text=document.getElementById("offer").innerHTML; //远程方法调用超时测试 function getOfferUseTimeOut(id) { MyTest.getOfferById(id,{callback: function(msg) { alert(msg.offerName); }, errorHandler:function(message) { alert("error:dwr调用超时!!"); }, timeout:10000} ); } //得到一个商品信息通过ID 传递参数测试 function getOfferById(id) { MyTest.getOfferById(id,callbackoffer2); } function callbackoffer2(msg) { alert(msg.offerName); } //翻转ajax测试,就是js->请求后台一个函数->后台函数在去调用前台页面上的JS函数 //得到一个商品信息通过ID 传递参数测试 function getOfferById2(id) { MyTest.getOfferById(id,callbackoffer2); } function callbackoffer2(msg) { alert(msg.offerName); sayHello(); } //翻转ajax测试,就是js->请求后台一个函数->后台函数动态创建前台页面上的JS函数,并调用 //得到一个商品信息通过ID 传递参数测试 function createJS(id) { MyTest.createJS(id,callback3); } function callback3(msg) { } //翻转ajax测试,就是js->请求后台一个函数->后台函数动调用前台页面上的JS函数 //得到一个商品信息通过ID 传递参数测试 function callJS(id) { MyTest.callJS(id,callback4); } function callback4(msg) { } //设置session 失效,便于测试dwr拦截 function invalidateSession(id) { MyTest.invalidateSession(id,callback5); } function callback5(msg) { } //为了测试dwr拦截构造的页面js函数 function logOut() { alert('session 超时'); } //得到一个商品信息 function getOffer() { MyTest.getOffer(callbackoffer); } function callbackoffer(msg) { text="商品ID:"+msg.offerId; text+=",商品名称:"+msg.offerName; //alert(msg.offerId); //alert(msg.offerName); text+="<br>" text+=" " for(i=0;i<msg.list.length;i++) { text+="产品ID:"+msg.list[i].productId+",产品名称:"+msg.list[i].productName; text+="<br>" text+=" " //alert(msg.list[i].productId); //alert(msg.list[i].productName); } //alert(text); document.getElementById("offer").innerHTML=text; } //得到一个商品list,商品中包含产品 function getOfferList() { MyTest.getOfferList(callbackofferlist); } function callbackofferlist(msg) { for(i=0;i<msg.length;i++) { alert("商品ID:"+msg[i].offerId); alert("商品名称:"+msg[i].offerName); for(j=0;j<msg[i].list.length;j++) { var product=msg[i].list[j]; alert("商品包含的产品ID:"+product.productId); alert("商品包含的产品名称:"+product.productName); } } } /* 商品对象返回中有一个list,其中包含了产品对象 我们可以使用这个list来验证select标签的例子 */ function getOption() { MyTest.getOffer(callback); } function callback(msg) { DWRUtil.removeAllOptions("product"); /* 如果下拉列表的中的内容是从服务器端的返回的list中构造的,可以这样 product是目标select区域的id,datalist是服务器返回的list, valueprop是作为select里面value值的那个对象属性的名称, textprop是作为select里面text值的那个对象属性的名称 */ /* 如果下拉列表的中的内容是从服务器端的返回的map中构造的,可以这样 参数true的意思是对象属性值用来作为选项的值 DWRUtil.addOptions('product',msg.map,true); */ DWRUtil.addOptions("product",msg.list,'productId','productName'); } function createBox() { MyTest.getProduct(callback2); } function callback2(msg) { DWRUtil.addRows("ss",msg,cellFunctions); } var cellFunctions = [ function(msg) { return msg.productId;}, function(msg) { return msg.productName;}, function(msg) { var editLink = document.createElement("input"); editLink.setAttribute("type","text"); editLink.setAttribute("value",msg.productName); return editLink; } ]; //为了测试翻转AJAX构造的页面js函数 function sayHello() { alert('你好,hxl'); } </script> </head> <body> <h1>DWR Test Page</h1> <br> <input type='button' value='点击更新下拉列表' onclick='getOption();'/><br> <input type='button' value='点击创建动态table' onclick='createBox();'/><br> <input type='button' value='测试返回商品对象' onclick='getOffer();'/><br> <input type='button' value='测试给远程方法传递参数' onclick="getOfferById('1001');"/><br> <input type='button' value='翻转Ajax(后台方法调用前台页面JS 方式1)' onclick="getOfferById2('1001');"/><br> <input type='button' value='翻转Ajax(后台方法动态在前台页面创建JS,并调用)' onclick="createJS('1001');"/><br> <input type='button' value='翻转Ajax(后台方法调用前台页面JS 方式2)' onclick="callJS('1001');"/><br> <input type='button' value='测试超时(3秒)' onclick="getOfferUseTimeOut('1001');"/><br> <input type='button' value='测试得到复杂商品集合对象' onclick='getOfferList();'/><br> 测试dwr 拦截器:我们通过session 的失效与否来验证拦截器,首先访问test.jsp,容器会为用户创建一个session,点击上面<br> 任何一个dwr方法都能正常执行,点击下面的按钮让session 失效后,在点击上面的dwr方法,将会拦截到session失效,不允许完成dwr调用 <br> <input type='button' value='测试dwr拦截器(手动让session失效)' onclick="invalidateSession('aaa')"/><br> <div id="demo1"></div> <table width="15" border="0" height="30"> <tbody id="table1"> <tr> </tr> </tbody> </table> <div id="offer"></div> <select id ="product"> <option>请选择</option> </select> <br> <table width="15" border="0" height="30"> <tbody id="ss"> <tr> </tr> </tbody> </table> </body> </html>
列子包含:
1.异步从服务器返回一个自定义的对象
2.从异步从服务器返回一个list,其中包含自定义的对象
3.给客户端的调用设置局部超时时间
4.客户端异常处理
5.客户端给远程方法传递入参
6.动态跟新下拉列表
7.动态生成 表格(有点问题,报js错误)
8.翻转ajax 就是 后台的函数调用前台JS,也就是页面上的回调函数在调用前台页面上的另一个js(方式1)
9.翻转ajax测试,就是js->请求后台一个函数->后台函数动态创建前台页面上的JS函数,并调用
10.翻转ajax 就是 后台的函数调用前台JS,也就是页面上的回调函数在调用前台页面上的另一个js(方式2)
11.dwr 拦截器测试
后期补充:没在提供的文档里
12. 如果前台dwr需要调用后台的一个业务方法,这个业务方法需要一个对象作为方法的参数,我们可以这么做
比如后台有个方法 public List<SysDict> querySysDict(SysDict dict)
首先配置
<convert match="cn.com.xinli.esup.beans.sys.SysDict" javascript="SysDict" converter="bean"></convert>
前台就可以这样王后台传递对象
/*异步添加消费类型*/
function getConsumerType()
{
var sd=new SysDict();
sd.itemName='消费终端';
JSDWRQuery.querySysDict(sd,function(msg)
{
DWRUtil.removeAllOptions("consumeType");
DWRUtil.addOptions("consumeType",msg,'itemId','itemName');
DWRUtil.addOptions( "consumeType", ['查询全部']);
});
}