之前对servlet的listener监听感觉陌生,不知道具体作用及用法,今天梳理了一下其作用,并相应做了以下的测试。
作用:
主要分三种,第一种是监听应用启动和关闭,需要实现ServletContextListener接口;
第二种是监听session的创建与销毁;属性的新增、移除和更改,需要实现HttpSessionListener和HttpSessionAttributeListener接口。
第三种是HttpSessionBindingListener接口
测试:
先配置web.xml:
代码:
<context-param>
<param-name>username</param-name>
<param-value>pandita</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>bsoft</param-value>
</context-param>
<listener>
<listener-class>com.pandita.servlet.listener.ApplicationListener</listener-class>
</listener>
<listener>
<listener-class>com.pandita.servlet.listener.SessionListener</listener-class>
</listener>
<listener>
<listener-class>com.pandita.servlet.listener.BindingListener</listener-class>
</listener>
第一种:实现ServletContextListener接口,接口有两个方法
1)public void contextInitialized(ServletContextEvent sce); //应用启动事件
2)public void contextDestroyed(ServletContextEvent sce); //应用停止事件
示例代码:
package com.pandita.servlet.listener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 监听web应用的启动和停止
* @author Bsoft
*
*/
public class ApplicationListener implements ServletContextListener {
public static long applicationInitialized = 0L;
/*应用停止事件*/
//测试时在myeclipse里面点击停止按钮无法触发此方法,进入tomcat的bin目录下执行shutdown.bat就可以看到输出语句
public void contextDestroyed(ServletContextEvent servletcontextevent) {
System.out.println("ApplicationListener : 监听到应用关闭了!");
}
/*应用启动事件*/
public void contextInitialized(ServletContextEvent servletcontextevent) {
applicationInitialized = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String datestr = sdf.format(new Date(applicationInitialized));
System.out.println("ApplicationListener : 监听到应用启动时间为 " + datestr);
}
}
第二种:实现HttpSessionListener和HttpSessionAttributeListener接口
1、HttpSessionListener接口有两个方法:
1)public void sessionCreated(HttpSessionEvent httpsessionevent);
2)public void sessionDestroyed(HttpSessionEvent httpsessionevent);
2、HttpSessionAttributeListener接口有三个方法:
1)public void attributeAdded(HttpSessionBindingEvent httpsessionbindingevent);
2)public void attributeRemoved(HttpSessionBindingEvent httpsessionbindingevent);
3)public void attributeReplaced(HttpSessionBindingEvent httpsessionbindingevent);
示例代码:
package com.pandita.servlet.listener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class SessionListener implements HttpSessionListener , HttpSessionAttributeListener {
private static int activeSessions = 0; //计算活动会话的数量
/*创建session*/
public void sessionCreated(HttpSessionEvent arg0) {
activeSessions ++ ;
System.out.println("SessionListener : 新建了一个session,当前session数量为" + activeSessions);
}
/*销毁session*/
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("SessionListener : session被销毁了,可以在销毁session的时候做一些操作");
}
/*在session中添加对象时触发此操作*/
@SuppressWarnings("unchecked")
public void attributeAdded(HttpSessionBindingEvent arg0) {
String attributeName = arg0.getName();
HttpSession session = arg0.getSession();
System.out.println("SessionListener : session被添加了属性" + attributeName + ",属性值为" + session.getAttribute(attributeName));
}
/*从session中移除对象时触发此操作*/
public void attributeRemoved(HttpSessionBindingEvent arg0) {
String attributeName = arg0.getName();
System.out.println("SessionListener : " + attributeName + "属性被从session上移除了");
}
/*当session中对象被重新设置时触发此操作*/
public void attributeReplaced(HttpSessionBindingEvent arg0) {
String attributeName = arg0.getName();
HttpSession session = arg0.getSession();
System.out.println("SessionListener : " + attributeName + "属性被重新设置值了,新值为" + session.getAttribute(attributeName));
}
}
第三种:实现HttpSessionBindingListener接口
1、接口的两个方法:
1).public void valueBound(HttpSessionBindingEvent event)
当对象正在被绑定到Session中,Servlet容器调用这个方法来通知该对象。
2).public void valueUnbound(HttpSessionBindingEvent event) 当从Session中删除对象时,Servlet容器调用这个方法来实现了HttpSessionBindingListener接 口的对象,而这个对象 可以利用HttpSessionBindingEvent对象来访问与它相联系的
HttpSession对象。
介绍:如果一个对象实现了HttpSessionBindingListener接口,当这个对象被绑定到Session中或者从session中被删除时,Servlet容器会通知这个对象,而这个对象在接收到通知后,可以做一些初始化或清除状态的操作。
作用:在线人数统计
利用HttpSessionBindingListener接口,编写一个在线人数统计的等程序。当一个用户登陆时,添加Session到在线人名单中,当一个用户退出时或者Session超时时,从在线人名单中删除该用户。
在OnlineUserList这个类中,应用单件模式,向程序提供一个全局访问点。
OnlineUserList.java类代码:
package com.pandita.servlet.listener;
import java.util.Enumeration;
import java.util.Vector;
public class OnlineUserList {
//单例模式
private static final OnlineUserList userlist = new OnlineUserList();
private Vector<String> v = new Vector<String>();
public OnlineUserList(){
}
public static OnlineUserList getInstance(){
return userlist;
}
public Enumeration<String> getUserList(){
return v.elements();
}
public int getUserCount(){
return v.size();
}
public boolean isExist(String username){
if(v.indexOf(username) >= 0){
return true;
}
return false;
}
public void addUser(String username){
if(username != null){
if(isExist(username)){
return ;
}
v.addElement(username);
}
}
public void removeUser(String username){
if(username != null){
v.removeElement(username);
}
}
}
BindingListener.java类代码:
package com.pandita.servlet.listener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class BindingListener implements HttpSessionBindingListener {
private String username = "";
private OnlineUserList userlist = OnlineUserList.getInstance();
public BindingListener(String username) {
this.username = username;
}
//启动加载监听类,上面定义了一个带参数的构造器,如不写出类的默认构造器,则会抛错:java.lang.InstantiationException
public BindingListener(){
}
public void setUserName(String username){
this.username = username;
}
public String getUserName(){
return this.username;
}
public boolean isExist(String username){
return userlist.isExist(username);
}
@SuppressWarnings("unchecked")
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("BindingListener : 我被当做属性绑定到session中了。");
userlist.addUser(this.username);
}
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("BindingListener : 我被session从属性列表中移除了。");
userlist.removeUser(this.username);
}
}
Servlet代码:
package com.pandita.servlet;
import java.io.IOException;
import java.io.OutputStreamWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @since 2014-07-29
* @author chenp
* @description 从资源库获取JavaScript文件
*/
public class ScriptLoader extends HttpServlet implements Servlet{
private static final long serialVersionUID = 5450443744150750822L;
public void init(ServletConfig config) throws ServletException {
}
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
/*1).获取session*/
HttpSession session = req.getSession(true);
System.out.println("getSession()方法触发了SessionListener监听类的sessionCreated()方法!");
/*2).session上加属性*/
session.setAttribute("username", session.getServletContext().getInitParameter("username"));
session.setAttribute("password", session.getServletContext().getInitParameter("password"));
System.out.println("session的setAttribute()方法触发了SessionListener监听类的attributeAdded()方法!");
/*3).从session上移除属性*/
session.removeAttribute("username");
System.out.println("session的removeAttribute()方法触发了SessionListener监听类的attributeRemoved()方法!");
/*4).更改session上属性的值*/
session.setAttribute("password", "bsoftbsoft");
/*5).绑定HttpSessionBindingListener对象到session属性列表*/
BindingListener bl = new BindingListener((String) session.getAttribute("username"));
session.setAttribute("binding", bl);
/*6).绑定HttpSessionBindingListener对象到session属性列表*/
session.removeAttribute("binding");
/*7).销毁session*/
session.invalidate();
System.out.println("session的invalidate()方法触发了SessionListener监听类的sessionDestroyed()方法!");
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
参考资料:http://blog.youkuaiyun.com/java_pengjin/article/details/6760175
http://blog.sina.com.cn/s/blog_634695420100ggg3.html