对应设计模式的Listener模式,事件触发时会自动触发该事件对应的Listener。主要监听session、request、context等进行监听。
Listener的概述
使用Listener和Event来完成相应事件的处理。
listener的使用
1 | import javax.servlet.http.HttpSession; |
1 | <listener> |
Listener的分类
8中listener,主要监听session、request、context的创建和销毁。6中Event
监听对象的创建和销毁
HttpSessionListener、ServletContextListener、ServletRequestListener分别用于监听Session、content、request的创建和销毁。
HttpSessionListener:创建Session时:sessionCreated(HttpSessionEvent se);超时或者执行session.invalidate()时: sessionDestroyed(HttpSessionEvent se)。用于收集在线信息。
ServletContextListener:服务启动或者热部署时:contextInitialized(ServletContextEvent event);服务器关闭或者只关闭web时:contextDestroyed(ServletContextEvent event)。该listener可用获取web.xml里面的配置的初始化信息。
ServletRequestListener:用户请求时:requestInitialized(ServletRequestEvent event);请求完成自动销毁时:requestDestroyed(ServletRequestEvent event)。如果html页面有多个图片会多次触发listener事件。
实例:监听session、request、context
1 | import javax.servlet.ServletContext; |
监听对象的属性变化
另一个Listener用于监听Session、context、request的属性变化,借口名格式为:xxxAttributeListener,包括HttpSessionAttributeListener、ServletContextAttributeListener、ServletRequestAttributeListener。当当向被监听对象添加、更新、移除属性时,会分别执行xxxAdded()/xxxReplaced()/xxxRemoved()方法,xxx分别代表Session、context、request。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SessionAttributeListenerTest implements
HttpSessionAttributeListener {
Log log = LogFactory.getLog(getClass());
// 添加属性
public void attributeAdded(HttpSessionBindingEvent se) {
HttpSession session = se.getSession();
String name = se.getName();
log.info("新建session属性:" + name + ", 值为:" + se.getValue());
}
// 删除属性
public void attributeRemoved(HttpSessionBindingEvent se) {
HttpSession session = se.getSession();
String name = se.getName();
log.info("删除session属性:" + name + ", 值为:" + se.getValue());
}
// 修改属性
public void attributeReplaced(HttpSessionBindingEvent se) {
HttpSession session = se.getSession();
String name = se.getName();
Object oldValue = se.getValue();
log.info("修改session属性:" + name + ", 原值:" + oldValue + ", 新值:"
+ session.getAttribute(name));
}
}
监听Session内的对象
HttpSessionBindingListener:当对象放到Session里面执行:valueBound(HttpSessionBindingEvent event);当对象从Session中移除时执行:valueUnbound(HttpSessionBindingEvent event)。对象必须实现Listener接口。
HttpSessionActivationListener:服务器关闭时会将Session里的内容保存到硬盘上,这个过程叫做钝化。服务器重新启动时会将Session内容从硬盘上重新加载。当Session里的内容被钝化时执行:sessionWillPassivate(HttpSessionEvent se);当对象重新加载时:sessionDidActivte(HttpSessionEvent se)。对象必须实现Listener接口。
1 | import java.io.Serializable; |
Listener使用案例
单点登录1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<jsp:directive.page import="com.helloweenvsfei.singleton.PersonInfo" />
<%
String action = request.getParameter("action");
String account = request.getParameter("account");
if("login".equals(action) && account.trim().length() > 0){
// 登录,将personInfo放入session
PersonInfo personInfo = new PersonInfo();
personInfo.setAccount(account.trim().toLowerCase());
personInfo.setIp(request.getRemoteAddr());
personInfo.setLoginDate(new java.util.Date());
session.setAttribute("personInfo", personInfo);
response.sendRedirect(response.encodeRedirectURL(request.getRequestURI()));
return;
}
else if("logout".equals(action)){
// 注销,将personInfo从session中移除
session.removeAttribute("personInfo");
response.sendRedirect(response.encodeRedirectURL(request.getRequestURI()));
return;
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
body {
font-size:12px;
}
</style>
</head>
<body>
<c:choose>
<c:when test="${ personInfo != null }">
<!-- 已经登录,将显示帐号信息 -->
欢迎您,${ personInfo.account }。<br/>
您的登录IP为${ personInfo.ip },<br/>
登录时间为<fmt:formatDate value="${ personInfo.loginDate }" pattern="yyyy-MM-dd HH:mm"/>。
<a href="${ pageContext.request.requestURI }?action=logout">退出</a>
<!-- 每5秒钟刷新一次页面 -->
<script>setTimeout("location=location; ", 5000); </script>
</c:when>
<c:otherwise>
<!-- 没有登录,将显示登录页面 -->
${ msg }
<c:remove var="msg" scope="session" />
<form action="${ pageContext.request.requestURI }?action=login" method="post">
帐号:
<input name="account" />
<input type="submit" value="登录">
</form>
</c:otherwise>
</c:choose>
</body>
</html>