读书笔记--监听器Listener

对应设计模式的Listener模式,事件触发时会自动触发该事件对应的Listener。主要监听session、request、context等进行监听。

Listener的概述

使用Listener和Event来完成相应事件的处理。

listener的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListenerTest implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println("新创建了一个session: " + session);
}

public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println("销毁了一个session: " + session);
}

}
1
2
3
4
5
<listener>
<listener-class>
com.helloweenvsfei.listener.SessionListenerTest
</listener-class>
</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
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
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ListenerTest implements HttpSessionListener,
ServletContextListener, ServletRequestListener {

Log log = LogFactory.getLog(getClass());

// 创建 session
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
log.info("新创建一个session, ID为: " + session.getId());
}

// 销毁 session
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
log.info("销毁一个session, ID为: " + session.getId());
}

// 加载 context
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
log.info("即将启动" + servletContext.getContextPath());
}

// 卸载 context
public void contextDestroyed(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
log.info("即将关闭" + servletContext.getContextPath());
}

// 创建 request
public void requestInitialized(ServletRequestEvent sre) {

HttpServletRequest request = (HttpServletRequest) sre
.getServletRequest();

String uri = request.getRequestURI();
uri = request.getQueryString() == null ? uri : (uri + "?" + request
.getQueryString());

request.setAttribute("dateCreated", System.currentTimeMillis());

log.info("IP " + request.getRemoteAddr() + " 请求 " + uri);
}

// 销毁 request
public void requestDestroyed(ServletRequestEvent sre) {

HttpServletRequest request = (HttpServletRequest) sre
.getServletRequest();

long time = System.currentTimeMillis()
- (Long) request.getAttribute("dateCreated");

log.info(request.getRemoteAddr() + "请求处理结束, 用时" + time + "毫秒. ");
}

}

监听对象的属性变化

另一个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接口。

扫描二维码关注公众号,回复: 7453313 查看本文章
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
72
73
74
75
76
import java.io.Serializable;
import java.util.Date;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PersonInfo implements HttpSessionActivationListener,
HttpSessionBindingListener, Serializable {

private static final long serialVersionUID = -4780592776386225973L;

Log log = LogFactory.getLog(getClass());

private String name;

private Date dateCreated;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Date getDateCreated() {
return dateCreated;
}

public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}

// 从硬盘加载后
public void sessionDidActivate(HttpSessionEvent se) {
HttpSession session = se.getSession();
log.info(this + "已经成功从硬盘中加载。sessionId: " + session.getId());
}

// 即将被钝化到硬盘时
public void sessionWillPassivate(HttpSessionEvent se) {
HttpSession session = se.getSession();
log.info(this + "即将保存到硬盘。sessionId: " + session.getId());
}

// 被放进session前
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
String name = event.getName();
log.info(this + "被绑定到session "" + session.getId() + ""的" + name
+ "属性上");

// 记录放到session中的时间
this.setDateCreated(new Date());
}

// 从session中移除后
public void valueUnbound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
String name = event.getName();
log.info(this + "被从session "" + session.getId() + ""的" + name
+ "属性上移除");
}

@Override
public String toString() {
return "PersonInfo(" + name + ")";
}

}

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>

原文:大专栏  读书笔记--监听器Listener


猜你喜欢

转载自www.cnblogs.com/wangziqiang123/p/11657700.html