功能需求:
有一个系统,当我们登录成功后,跳转到success.jsp页面。多人登录,每个人都会停留在这个页面。此事,我只想给一个账号叫aaa的人的success.jsp页面推送信息;其他人的success.jsp接收不到。
思路:
当一个页面调用dwr生成的js时,会产生一个scriptSession。类似与session,是一个唯一标示符。根据这个scriptSession我们可以知道到底要推给哪一个页面。鉴于此:
1.在登录的时候,我们将登录的人的信息放入到session里面(这里是session,而不是scriptSession);这一步是在login.jsp页面提交后跳转到loginAction里面实现。
2.在登录成功后,加载success.jsp页面时,我们出发一个dwr生成的js里面的方法,此事产生一个scriptSession,我们将session中的个人信息取出来,将用户名存入scriptSession中;
3.在发送页面,push.jsp;当我们点击发送时,遍历所有的scriptSession,在scriptSession找到用户名,推送。
代码目录:
具体代码:
<span style="font-size:14px;">public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}</span>
下面定义管理器和监听器:
<span style="font-size:14px;">public class DwrScriptSessionManagerUtil extends DefaultScriptSessionManager {
private static final long serialVersionUID = -7504612622407420071L;
public DwrScriptSessionManagerUtil(){
System.out.println("正在启动scriptSessionManager...");
this.addScriptSessionListener(new DwrScriptSessionListener());
}
}
</span>
<span style="font-size:14px;">public class DwrScriptSessionListener implements ScriptSessionListener{
// public static final List list = new ArrayList<Map>();
@Override
public void sessionCreated(ScriptSessionEvent event) {
// TODO Auto-generated method stub\
System.out.println("create a new scriptSession");
WebContext context = WebContextFactory.get();
HttpSession session = context.getSession();
ScriptSession scriptSession = event.getSession();
System.out.println(scriptSession.getId());
//session中的username放入到scriptSession中
scriptSession.setAttribute("username", ((User)session.getAttribute("user")).getName());
}
@Override
public void sessionDestroyed(ScriptSessionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("destroy the old scriptSession");
WebContext context = WebContextFactory.get();
HttpSession session = context.getSession();
}
}</span>
登录:
<span style="font-size:14px;">public class Login extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
HttpSession session = request.getSession();
User user = new User();
user.setName(username);
user.setPassword(password);
session.setAttribute("user", user);
response.sendRedirect("success.jsp");
}
<span style="font-size:18px;">}</span></span>
推送:
<span style="font-size:14px;">public class PushMessage {
public void pushMessage(String name,String content){
System.out.println("准备发送消息");
final String username = name;
final String autoMessage = content;
WebContext context = WebContextFactory.get();
Browser.withAllSessionsFiltered(new ScriptSessionFilter(){
public boolean match(ScriptSession session) {
//这里判断session里面保存的用户信息,获取scriptSession的情况
if(username.equals((String)session.getAttribute("username")))
return true;
return false;
}
}, new Runnable(){
private ScriptBuffer script = new ScriptBuffer();
@Override
public void run() {
// TODO Auto-generated method stub
script.appendCall("showMessage", autoMessage);
Collection<ScriptSession> sessions = Browser.getTargetSessions();
for (ScriptSession scriptSession : sessions){
scriptSession.addScript(script);
}
}
});
}
}</span>
<span style="font-size:14px;">public class InitRecieve {
public void initMessage(String username){
System.out.println("初始化将要显示推送信息的页面");
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
scriptSession.setAttribute("username", username);
System.out.println(scriptSession.getId());
HttpSession session = WebContextFactory.get().getSession();
System.out.println(((User)session.getAttribute("user")).getName());
}
}</span>
配置文件:
web.xml
<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<listener>
<listener-class>org.directwebremoting.servlet.DwrListener</listener-class>
</listener>
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<!-- 是否可以从别的域进行请求 -->
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<!-- 解决找不到注释类产生的报错 -->
<init-param>
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
<!-- 启动逆ajax,也就是推 -->
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- 启动自定义管理scriptSession -->
<init-param>
<param-name>org.directwebremoting.extend.ScriptSessionManager</param-name>
<param-value>com.mz.dwr.DwrScriptSessionManagerUtil</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>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginAction</servlet-name>
<servlet-class>com.mz.action.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginAction</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
</web-app></span>
dwr.xml
<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<!-- 通用dwr配置 -->
<dwr>
<allow>
<!-- 建立JS对象,将目标对象的方法转换成JS对象的方法 -->
<create creator="new" javascript="initRecieve" >
<param name="class" value="com.mz.action.InitRecieve"></param>
</create>
<create creator="new" javascript="pushMessage">
<param name="class" value="com.mz.action.PushMessage"></param>
</create>
</allow>
</dwr></span>
JSP页面:
login.jsp
<span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="login.do" method="post">
<input type="text" id="username" name="username"><br/>
<input type="password" id="password" name="passoword"><br/>
<input type="submit" value="send"/>
</form>
</body>
</html></span>
success.jsp
<span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type='text/javascript' src='${pageContext.request.contextPath}/dwr/engine.js'></script>
<script type='text/javascript' src='${pageContext.request.contextPath}/dwr/util.js'></script>
<!--在线jquery库--> <script type='text/javascript' src='${pageContext.request.contextPath}/dwr/interface/initRecieve.js'></script>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
function init(){
//开启推送
dwr.engine.setActiveReverseAjax(true);
//销毁或刷新页面时销毁当前ScriptSession
dwr.engine.setNotifyServerOnPageUnload(true);
//服务器关闭,取消dwr弹的错误提示框
dwr.engine.setErrorHandler(function(){});
}
function onPageLoad(){
initRecieve.initMessage('${user.name}');
}
function showMessage(autoMessage){
alert("s");
$("#show").text(autoMessage);
}
</script>
</head>
<body οnlοad="init(); onPageLoad();">
<div id="show"></div>
</body>
</html></span>
push.jsp
<span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<script type='text/javascript' src='${pageContext.request.contextPath}/dwr/engine.js'></script>
<script type='text/javascript' src='${pageContext.request.contextPath}/dwr/util.js'></script>
<script type='text/javascript' src='${pageContext.request.contextPath}/dwr/interface/pushMessage.js'></script>
<script type="text/javascript">
function init(){
//开启推送
//销毁或刷新页面时销毁当前ScriptSession
dwr.engine.setNotifyServerOnPageUnload(true);
//服务器关闭,取消dwr弹的错误提示框
}
function test() {
var username = document.getElementById("username").value;
var content = document.getElementById("content").value;
//msg = {msgId: '1', context: $("#msgContext").val()};
pushMessage.pushMessage(username,content);
// location.reload();
}
</script>
</head>
<body >
username : <input type="text" name="username" id="username" /> <br />
<input type="text" id="content"/>
<input type="button" value="Send" οnclick="test()" />
</body>
</html></span>
测试方法:
启动项目后,打开多个login.jsp;任意输入账号密码;
打开push.jsp; 输入刚才登录的其中一个账号;并且输出内容;查看变化。
问题:
上面说了,每当调用页面里面由dwr产生的js时都会创建一个scriptSession,所以在发送发送消息是,会发现多产了一个ScriptSession.由于我是在后台Quartz不断调度任务进行推的。所以没有用到页面推送,也就没解决这个问题。但是我觉的,在发送后立即刷新页面应该是一个解决方法。
代码打包,附上连接: