这几天做项目,需要一个消息提醒功能,决定用 dwr 实现,在 dwr 官网和网上找了很多资料,也没实现精准推送,大多数的例子具体步骤写的不清楚,不怎么了解 dwr 的人看了也未必能看懂,反正我是没看懂,那时就决定,若自己实现了,一定将具体步骤写下来,希望能给那些和我一样的人一些帮助,若有不明白的,可以给小弟留言。我只写步骤,不写原理,下面开始。
第一、在项目中引入 dwr.jar,然后在 web.xml 中进行配置,配置如下:
<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>
第二:在 web.xml 的同级目录下新建 dwr.xml 文件,内容如下
<!DOCTYPE dwr PUBLIC
“-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN”
“http://getahead.org/dwr/dwr30.dtd”>
<dwr>
<alow>
<create creator=”new” javascript=”MessagePush”>
<param name=”class” value=”com.huatech.messageremind.service.MessagePush”/>
</create>
</alow>
</dwr>
这个是 dwr 的基本配置,MessagePush 在页面的 javascript 中使用,com.huatech.messageremind.service.MessagePush 实现了想要调用的方法,MessagePush 我觉得就相当于 java 类中的一个映射,在 javascript 中使用 MessagePush.java 类中实现的方法,即可在 dwr 中调用。
第三,要想使用 dwr,还要在你想要推送的页面中引入 script,
<script type=”text/javascript” src=”<%=basepath%>dwr/engine.js”></script>
<script type=”text/javascript” src=”<%=basepath%>dwr/util.js”></script>
<script type=”text/javascript” src=”<%=basepath%>dwr/interface/MessagePush.js”></script>
可以看见,也引入了 dwr.xml 中配置的 javascript,engine.js 和 util.js 是必须引入的。
以上三点都是基本配置,没什么好说的,想使用 dwr,就得这么做。
第四,实现消息的精准推送
消息推送简单,但是想实现精准推送就需要做一些别的操作了
1 在任何一个用户登录的时候,都需要将其 userId 或者其他唯一性标识放入 session 中,我放的是 userId,
这里就以 userId 为唯一性标识。
2 在载入想推送的页面时,需要 onload 一个我在 MessagePush 类中实现的方法,当然了,需要使用 dwr 调用
js 的调用方法如下:
function onPageLoad(){
var userId = ‘${userinfo.humanid}’;
MessagePush.onPageLoad(userId);
}
<body onload=”dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);onPageLoad();> 在 onload 中的三个函数都是必须的,其中 dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);是 dwr 中的函数。
MessagePush 类中实现的方法如下:
public void onPageLoad(String userId) {
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
scriptSession.setAttribute(userId, userId);
DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
try {
dwrScriptSessionManagerUtil.init();
} catch (ServletException e) {
e.printStackTrace();
}
}
大家注意到,onPageLoad 方法中还有一个名为 DwrScriptSessionManagerUtil 的类,该类如下实现:
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()+””;
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);
}
}
第四步是最最重要的,为了第四步我研究了两天多,下面开始消息推送。
第五、消息推送
在你想要推送消息的时候,调用如下方法:
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);
}
}
});
}
userid 即为你想推给消息的人,message 为你想推送的消息,大家注意到这里 script.appendCall(“showMessage”, autoMessage);
其中 showMessage 为在想推送的页面中的 javascript 方法,autoMessage 是这个方法的参数,这样那个页面就能得到推送的内容了,至于如何展现,就看你的需要了。
至此,一个 dwr 消息精准推送的步骤就写完了,其实很多东西都不难,只是我们不知道该怎么用而已。