按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
anni。TestServlet
TestServlet
/TestServlet
直接指定 servlet…name,TestFilter 便会引用 TestServlet 配置的
url…pattern,在某些 filter 与 servlet 绑定的情况下不失为一个好办法。
77 / 148
…………………………………………………………Page 78……………………………………………………………
第 8 章 配置 listener 监听器
注意
还记得我们之前讲过的在线列表吗?第 4。2 节 “例子:在线列表”。我们曾经
说过那个在线列表无法判断用户非法退出,很可能造成在线列表无限增大,现在
我们可以用 listener 来弥补这一问题了。
如果你不满足以下任一条件,请继续阅读,否则请跳过此后的部分,进入下一章:
第 9 章 封装 taglib 组件。
1。 了解如何使用HttpSessionListener 监听 session 的销毁。
2。 了解如何使用 HttpSessionBindingListener 监听 session 的销毁。
8。1。 使用 HttpSessionListener
编写一个 OnlineUserListener。
package anni;
import java。util。List;
import javax。servlet。ServletContext;
import javax。servlet。http。HttpSession;
import javax。servlet。http。HttpSessionListener;
import javax。servlet。http。HttpSessionEvent;
public class OnlineUserListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
}
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event。getSession();
ServletContext application = session。getServletContext();
// 取得登录的用户名
String username = (String) session。getAttribute(〃username〃);
// 从在线列表中删除用户名
List onlineUserList = (List)
application。getAttribute(〃onlineUserList〃);
onlineUserList。remove(username);
78 / 148
…………………………………………………………Page 79……………………………………………………………
System。out。println(username + 〃超时退出。〃);
}
}
OnlineUserListener 实现了 HttpSessionListener 定义的两个方法:
sessionCreated()和 sessionDestroyed()。这两个方法可以监听到当前应用中
session 的创建和销毁情况。我们这里只用到 sessionDestroyed()在 session
销毁时进行操作就可以。
从 HttpSessionEvent 中获得即将销毁的 session,得到 session 中的用户名,
并从在线列表中删除。最后一句向 console 打印一条信息,提示操作成功,这只
是为了调试用,正常运行时删除即可。
为了让监听器发挥作用,我们将它添加到 web。xml 中:
anni。OnlineUserListener
以下两种情况下就会发生 sessionDestoryed (会话销毁)事件:
1。 执行 session。invalidate()方法时。
既然 LogoutServlet。java 中执行 session。invalidate()时,会触发
sessionDestory()从在线用户列表中清除当前用户,我们就不必在
LogoutServlet。java 中对在线列表进行操作了,所以
LogoutServlet。java 的内容现在是这样。
public void doGet(HttpServletRequest request;HttpServletResponse
response)
throws ServletException; IOException {
// 销毁 session
request。getSession()。invalidate();
// 成功
response。sendRedirect(〃index。jsp〃);
}
2。 如果用户长时间没有访问服务器,超过了会话最大超时时间,服务器就会
自动销毁超时的session。
79 / 148
…………………………………………………………Page 80……………………………………………………………
会话超时时间可以在 web。xml 中进行设置,为了容易看到超时效果,我们
将超时时间设置为最小值。
1
时间单位是一分钟,并且只能是整数,如果是零或负数,那么会话就永远
不会超时。
对应例子在 08…01,为了验证 OnlineUserListener 是否能正常执行,我们可以
登录两个用户,其中一个点击注销,另一个等待一分钟,然后可以在 console
中看到输出的信息。
8。2。 使用 HttpSessionBindingListener
HttpSessionBindingListener 虽然叫做监听器,但使用方法与
HttpSessionListener 完全不同。我们实际看一下它是如何使用的。
我们的OnlineUserBindingListener 实现了HttpSessionBindingListener接口,
接口中共定义了两个方法:valueBound()和 valueUnbound(),分别对应数据绑
定,和取消绑定两个事件。
所谓对 session 进行数据绑定,就是调用 session。setAttribute()把
HttpSessionBindingListener 保存进 session 中。我们在LoginServlet。java
中进行这一步。
// 把用户名放入在线列表
80 / 148
…………………………………………………………Page 81……………………………………………………………
session。setAttribute(〃onlineUserBindingListener〃; new
OnlineUserBindingListener(username));
这就是HttpSessionBindingListener和HttpSessionListener之间的最大区别:
HttpSessionListener 只需要设置到 web。xml 中就可以监听整个应用中的所有
session。HttpSessionBindingListener 必须实例化后放入某一个 session 中,
才可以进行监听。
从监听范围上比较,HttpSessionListener 设置一次就可以监听所有 session,
HttpSessionBindingListener 通常都是一对一的。
正是这种区别成就了 HttpSessionBindingListener 的优势,我们可以让每个
listener 对应一个 username,这样就不需要每次再去 session 中读取username,
进一步可以将所有操作在线列表的代码都移入 listener,更容易维护。
valueBound()方法的代码如下:
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = event。getSession();
ServletContext application = session。getServletContext();
// 把用户名放入在线列表
List onlineUserList = (List)
application。getAttribute(〃onlineUserList〃);
// 第一次使用前,需要初始化