最近工作需要写一个后台推送消息到浏览器提示用户操作的功能,在网上摸索了几天,有的是比较乱的,会造成一些误导,现在把自己应用笔记写下来跟大家分享。
第一步:下载dwr.jar、commons-logging.jar(我这里用的是dwr3.0)导入到自己的工程里。
第二步:修改web.xml,加入以下code
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>allowScriptTagRemoting</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>3000</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
第三步:编写java类
1.MessagePush类
package com.dwr.messagemind.service;
import javax.servlet.ServletException;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;
import com.dwr.messagemind.servlet.DwrScriptSessionManagerUtil;
public class MessagePush {
public void onPageLoad(String userId) {
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
System.out.println("scriptSession:" + scriptSession);
scriptSession.setAttribute("userId", userId);
DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
try {
dwrScriptSessionManagerUtil.init();
} catch (ServletException e) {
e.printStackTrace();
}
}
}
2.DwrScriptSessionManagerUtil类
package com.dwr.messagemind.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import org.directwebremoting.Container;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.extend.ScriptSessionManager;
import org.directwebremoting.servlet.DwrServlet;
public class DwrScriptSessionManagerUtil extends DwrServlet {
private static final long serialVersionUID = -7504612622407420071L;
public void init() throws ServletException {
Container container = ServerContextFactory.get().getContainer();
ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
ScriptSessionListener listener = new ScriptSessionListener() {
public void sessionCreated(ScriptSessionEvent ev) {
HttpSession session = WebContextFactory.get().getSession();
//String userId = ((User) session.getAttribute("userinfo")).getHumanid() + "";
String userId = "123";
System.out.println("a ScriptSession is created!");
ev.getSession().setAttribute("userId", userId);
}
public void sessionDestroyed(ScriptSessionEvent ev) {
System.out.println("a ScriptSession is distroyed");
}
};
manager.addScriptSessionListener(listener);
}
}
3.DwrTool类(前台页面在需要推送的地方调用此类的方法)
package com.dwr.messagemind.service;
import java.util.Collection;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
public class DwrTool {
public void sendMessageAuto(String userid, String message) {
final String userId = userid;
final String autoMessage = message;
Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
public boolean match(ScriptSession session) {
if (session.getAttribute("userId") == null) {
return false;
} else {
return (session.getAttribute("userId")).equals(userId);
}
}
}, new Runnable() {
private ScriptBuffer script = new ScriptBuffer();
public void run() {
script.appendCall("showMessage", autoMessage);
Collection<ScriptSession> sessions = Browser.getTargetSessions();
for (ScriptSession scriptSession : sessions) {
scriptSession.addScript(script);
}
}
});
}
}
第四步:配置dwr.xml,在web.xml同级位置新建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="new" javascript="MessagePush">
<param name="class" value="com.dwr.messagemind.service.MessagePush"/>
</create>
<create creator="new" javascript="DwrTool">
<param name="class" value="com.dwr.messagemind.service.DwrTool"/>
</create>
</allow>
</dwr>
第五步:编写jsp页面测试
接收页面需要做以下变动:
<script type="text/javascript" src="<%=path%>/dwr/engine.js"></script>
<script type="text/javascript" src="<%=path%>/dwr/util.js"></script>
<script type="text/javascript" src="<%=path%>/dwr/interface/MessagePush.js"></script>
<script type="text/javascript">
function onPageLoad(){
MessagePush.onPageLoad("123");
}
function showMessage(autoMessage) {
alert(autoMessage);
document.all.bb.innerHTML = autoMessage;
}
</script>
<body onload="dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);onPageLoad();">
前两项为dwr配置,第三个调用js方法出发MessagePush.onPageLoad('')方法,注意MessagePush为在dwr中配置的类名,并且需要在页面引入MessagePush.js,这个为系统自动生成,不需要自己创建.engine.js、util.js也为系统自动生成,不需要自己创建,只许引入即可。
发送页面做以下配置
引入
<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/engine.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/util.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/interface/DwrTool.js"></script>
<script type="text/javascript">
function send(message) {
DwrTool.sendMessageAuto("123", message);
}
</script>
在需要调用的地方调用js方法send('')即可。
注:因为dwr用的ajax反转方式实现推送,所以如果在ajax方法里调用send()是没有效果的,会报异常,当然在发送页面将dwr设置成同步方式可以发送成功(我实验的时候会先弹出一个错误窗口,但是还可以实现效果),只许在<body>加入
onlocad="dwr.engine.setAsync(false);"
当然如果出现弹出错误窗口交互不好,继续想办法,既然不能在ajax里面调用,还希望成功的时候调用send(),那就用<iframe>吧,
<form action="你要请求的servlet" method="post" id="inputform" name="inputform" target="hidden_frame">
<iframe id="hidden_frame" name="hidden_frame" style="display: none;"></iframe>
接下来提交form到后台servlet,后台处理成功之后调用send();
response.getWriter().print("<script>");
response.getWriter().print("parent.send('成功了');");
response.getWriter().print("</script>");
至此已经都说完了,如果有疑问请留言吧。