最近一个项目是使用DWR+JQuery开发的,下面简单谈谈我的一些心得:
什么是DWR?DWR(Direct Web Remoting)是Java和JavaScript相结合的开源库,通过它可以简单、容易地构建Ajax程序,开发者无需了解 XMLHttpRequest的编码细节。通过客户端的JavaScript采用看似调用浏览器本地代码的方法来调用服务器端的代码,这即是DWR中“直 接”的含义。DWR的显著特征就是提供服务端代码视为浏览器中JavaScript代码的方法。本质上DWR就是一种RPC(Remote Procedure Call,远程过程调用)。
一言以蔽之,DWR就是让你简便快捷地实现前后台的ajax交互。
有人说,JQuery的$.ajax方法已经足够用了,自己手写封装ajax请求方法也可以,干嘛还要用DWR呢?我认为有必要使用DWR,它虽然需要添加一些配置,但使用起来真的很方便,调用后台服务的js代码比jQuery简洁多了(当然比我亲自写的更要简洁),它能用与Spring集成,直接使用Spring的Bean,这个功能很好用的哦。DWR甚至可以用来做无刷新文件上传和下载(当然jQuery也可以),这个将在我的另一篇文章里做介绍。
下面是请求的流程图:
再讲一下配置:
1.web.xml:
<!-- DWR Servlet -->
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/config/dwr.xml</param-value>
</init-param>
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
2.WEB-INF/config/dwr.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">
<dwr>
<allow>
<create creator="spring" javascript="JasperReportService">
<param name="beanName" value="jasperReportService"/>
</create>
<create creator="new" javascript="IdentificationAction">
<param name="class" value="com.sch.wms.web.jsaction.CheckIdentificationAction"/>
</create>
<convert match="com.sch.wms.web.jsaction.User" converter="bean"/>
<create creator="spring" javascript="JsShipmentOrderAction">
<param name="beanName" value="jsShipmentOrderSearchAction"/>
</create>
<create creator="new" javascript="FileUpload">
<param name="class" value="com.sch.common.FileUpload" />
</create>
<convert match="com.sch.wms.web.form.UserSchemaForm" converter="bean">
<param name="include" value="uid,userSchema,schemaList,countryList,userId,errMessage" />
</convert>
<create creator="new" javascript="CommonFunction">
<param name="class" value="com.sch.common.CommonFunction"/>
</create>
</allow>
</dwr>
3.lib下面加入dwr.jar,当前最新版本是3.0。
与DWRServlet相对应,客户端的DWR核心是engine.js,它通过嵌入HTML页面中的脚本
<script src='/[YOUR-WEBAPP]/dwr/engine.js'></script>
被浏览器下载到本地。engine.js中包含的JavaScript库用于将来自于动态生成的代理存根的调用组装为服务器上真正的对象,负责完成 远程通信和调用过程。engine.js会输出DWREngine对象,通过它用户可以配置客户端同服务端通信的具体方式,比如:同步还是异步、采用 Http传输方法、rpcType、超时等参数。
此外HTML页面中通常还会嵌入<script src='/[YOUR-WEBAPP]/dwr/util.js'></script>,util脚本作为工具集将辅助对数据的处理,比如动态刷新页面。
示例:
<script type='text/javascript' src='<%=request.getContextPath() %>/dwr/engine.js'></script>
<script type='text/javascript' src='<%=request.getContextPath() %>/dwr/util.js'></script>
<script src='<%=request.getContextPath() %>/dwr/interface/JsShipmentOrderAction.js'></script>
front-end 的js调用后台代码:
dwr.engine.setAsync(false);
JsShipmentOrderAction.getOutboundList(form, function(data){
alert(data);
//你的callback处理
});
dwr.engine.setAsync(true);
说明一下:在invoke的前后加上dwr.engine.setAsync(false); 和 dwr.engine.setAsync(true);是为了让通信保持同步。这两句必须同时加上。server后台代码:
public List getOutboundList(ShipmentOrderSearchForm form,
HttpServletRequest request, HttpServletResponse response,
ServletContext context) {
logger.info("JS Action:getOutboundList");
List dataList = new ArrayList();
UserProfile profile = (UserProfile) request.getSession().getAttribute(
"userProfile");
String dbprofile = getDbProfile(profile.getUserID());
Integer schema = FindDataSourceService.getCurrentUserSchemaId(request
.getSession());
dataList = soDao.getOutboundList(form, dbprofile, schema);
return dataList;
}
好了,一个大概的DWR请求就OK了。