dwr推事例
之前想弄一个监控系统运行情况的程序,后来用了监控宝所以程序没有往下写,于是把程序改成了练习一下dwr推技术,也叫ajax反转。用到的版本应该是dwr2.4。程序是在服务启动的时候开启一个线程定时访问要监控的系统,然后把一些信息写到数据库。文章主要是记录在调用写到数据库的方法后(用到了spring拦截器),利用dwr把刚写入数据库的一些信息输出到页面。关于dwr的环境搭建就不说了,只说一下要用推(ajax反转)要在web.xml中如下配置:
<!-- dwr 配置开始--> <!-- 1、piggyback方式 这是默认的方式。 如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。 只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。 2、comet方式 当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。 服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。 3、polling方式 由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送ajax请求,然后查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。 --> <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> <!-- DWR默认采用piggyback方式 --> <!-- 使用polling和comet的方式 --> <init-param> <param-name>pollAndCometEnabled</param-name> <param-value>true</param-value> </init-param> <!-- comet方式 --> <!-- <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> --> <!-- polling方式:在comet方式的基础之上,再配置以下参数 --> <!-- <init-param> <param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name> <param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value> </init-param> --> <!-- 毫秒数。页面默认的请求间隔时间是5秒 --> <!-- <init-param> <param-name>disconnectedTime</param-name> <param-value>60000</param-value> </init-param> --> <init-param><param-name>crossDomainSessionSecurity</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dwr-invoker</servlet-name><url-pattern>/dwr/*</url-pattern></servlet-mapping><listener> <listener-class> org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener </listener-class> </listener><listener> <listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextListener</listener-class> </listener><!-- dwr 配置结束-->
spring的拦截器拦截器拦截的如下方法saveMonitor,此方法写入数据到数据库
<!-- 系统拦截器配置begin --><bean id="monitorInterceptor"name="code">package com.adtech.servlet;import java.lang.reflect.Method;import java.util.List;import org.springframework.aop.AfterReturningAdvice;import com.adtech.domain.Monitor;import com.adtech.dwr.DwrPush;/** * 描述: * copyright:adtech * 作者:lujiangnan * 创建时间:2011-7-31 */public class MonitorInterceptor implements AfterReturningAdvice{ //要拦截的方法名集合private List<String> methodNames;public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {try { //判断当前方法是否要拦截的方法for (int i=0,j=methodNames.size();i<j;i++){if (methodNames.get(i).equals(method.getName())){if(DwrPush.wctx !=null){DwrPush.sendMessage((Monitor)args[0]);}break;}} //如果不是,直接返回} catch (Exception e) {}} public List<String> getMethodNames() { return methodNames; } public void setMethodNames(List<String> methodNames) { this.methodNames = methodNames; }}dwr.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" " http://www.getahead.ltd.uk/dwr/dwr10.dtd "><dwr><allow><convert match="java.lang.Exception" converter="exception"> <param name='include' value='message'/></convert> <convert match="java.lang.StackTraceElement" converter="bean"/><create creator="new" javascript="dwrPush" ><param name="class" value="com.adtech.dwr.DwrPush" /><include method="sendMessage"/></create><convert match="com.adtech.domain.Monitor" converter="bean" /></allow></dwr>
以下便是dwr中的推方法,也是页面取数据的类,其中Monitor 是javabean.
/** * 类描述: dwr推 * copyright: * author:lujiangnan * date:2011-7-27 * @version */public class DwrPush{public static WebContext wctx = null;public static void sendMessage(Monitor monitor){if(wctx == null){wctx = WebContextFactory.get();} ScriptBuffer script = new ScriptBuffer(); //执行js 方法if(monitor != null){ StringBuffer sb = new StringBuffer(); sb.append(monitor.getId()).append(","); sb.append(monitor.getMessage()).append(","); sb.append(monitor.getAccessTime()).append(","); sb.append(monitor.getAccessName()).append(","); sb.append(monitor.getTotalTime()); script.appendScript("receiveMessages('").appendData(sb.toString()).appendScript("');");} ServerContext sctx = ServerContextFactory.get(wctx.getServletContext()); Collection<ScriptSession> scriptSessions = sctx.getScriptSessionsByPage(wctx.getCurrentPage()); Util util = new Util(scriptSessions); //可以设置样式等 // util.setStyle("test", "display", "none"); for (ScriptSession session : scriptSessions) { session.addScript(script); }}}jsp页面主要代码如下:
<script>function getData(){ dwrPush.sendMessage(null);} function receiveMessages(message) { var msg = eval("("+message+")"); var temp = msg.split(","); var num = temp[0]; var status = temp[1]; var accessTime = new Date(temp[2]).format('yyyy-MM-dd hh:mm:ss'); var accessName = temp[3]; var totalTime = temp[4];var newRow = document.getElementById('tableData').insertRow(2);var cell0 = newRow.insertCell(0);var cell1 = newRow.insertCell(1);var cell2 = newRow.insertCell(2);var cell3 = newRow.insertCell(3);var cell4 = newRow.insertCell(4);cell0.innerHTML = num;cell1.innerHTML = status;if(status =="连接失败"){cell1.style.color = 'red';}cell2.innerHTML = accessTime;cell3.innerHTML = accessName;cell4.innerHTML = totalTime;} Date.prototype.format = function(format){.......}</script>///此处是关键 <body onload="DWREngine.setActiveReverseAjax(true); getData();"><div align="center"><TABLE title=监控记录表 align="center" id="tableData"><tr id="titleData"><td colspan="4">系统连接监控记录表</td><td colspan="1" onclick="getData()" style="size: 10px"><a href="<c:url value='/monitorResult/monitor.htm?action=getMonitorRecord'/>">更多</a></td></tr><TR id="headData" bgcolor="#fffce7" style="color:#968054"><TD width="9%">序号</TD><TD width="20%">连接状态</TD><TD width="33%">访问时间</TD><TD width="22%">系统地址</TD><TD>响应时间</TD> </TR></TABLE></DIV> </body>效果图为每次数据库有更新在表格数据的第一行添加一行,图:
[img]

[/img]
因为本身也不太懂,是做着玩的,希望朋友们可以指点改进一下。
1 楼 zhmy0129 2011-09-26 呵呵 先收了 有时间看~