监听器:监听器就是一个java程序,功能是监听另一个java对象变化(方法调用、属性变更)
8个监听器,分为了3种
写一个类实现响应的接口
注册监听器 -- 在web.xml中注册监听器
1.用来监听三大作用域的创建和销毁的监听器
ServletContextListener 用来监听ServletContext对象创建和销毁的监听器
创建:服务器启动,web应用加载后立即创建代表当前web应用的ServletContext对象
销毁:服务器关闭或web应用被移除出容器时,随着web应用的销毁而销毁
HttpSessionListener 用来监听HttpSession对象创建和销毁的监听器
创建:第一次调用request.getSession方法时创建代表当前会话的session对象
销毁:超过30分钟没人用销毁/调用invalidate方法自杀/服务器非正常关闭时随着web应用的销毁而销毁,如果服务器是正常关闭会被钝化起来.
当服务器正常关闭时,还存活着的session会随着服务器的关闭被以文件的形式存储在tomcat的work目录下,这个过程叫做session的钝化
当服务器再次正常开启时,服务器会找到之前的SESSIONS.ser文件从中恢复之前保存起来的session对象这个过程叫做session的活化
想要随着Session被钝化活化的对象它的类必须实现Serializable接口
ServletRequestListener 用来监听ServletRequest对象创建和销毁的监听
创建:请求开始创建代表请求的request对象
销毁:请求结束时代表请求的request对象销毁
package com.dzq.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * 监听ServletContext创建和销毁的监听器 * @author * */ @WebListener public class MyServletContextListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext对象被销毁了"+sce.getServletContext()); } @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext对象被创建出来了"+sce.getServletContext()); } }
package com.dzq.listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; @WebListener public class MySRListener implements ServletRequestListener { public void requestDestroyed(ServletRequestEvent arg0) { System.out.println("request对象被销毁"+arg0.getServletRequest()); } public void requestInitialized(ServletRequestEvent arg0) { System.out.println("request对象被创建"+arg0.getServletRequest()); } }
package com.dzq.listener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; @WebListener public class MySessionListener implements HttpSessionListener { public void sessionCreated(HttpSessionEvent arg0) { System.out.println("session对象被创建"+arg0.getSession()); } public void sessionDestroyed(HttpSessionEvent arg0) { System.out.println("session对象被销毁"+arg0.getSession()); } }
2.用来监听三大作用域中属性变化的监听器
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
package com.dzq.listener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; @WebListener public class MyHSAttribute implements HttpSessionAttributeListener { public void attributeAdded(HttpSessionBindingEvent arg0) { } public void attributeRemoved(HttpSessionBindingEvent arg0) { } public void attributeReplaced(HttpSessionBindingEvent arg0) { } }
package com.dzq.listener; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.annotation.WebListener; @WebListener public class MyServletAttribute implements ServletRequestAttributeListener { public void attributeRemoved(ServletRequestAttributeEvent arg0) { } public void attributeAdded(ServletRequestAttributeEvent arg0) { } public void attributeReplaced(ServletRequestAttributeEvent arg0) { } }
package com.dzq.listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import javax.servlet.annotation.WebListener; @WebListener public class MySCAttributeListener implements ServletContextAttributeListener { public void attributeAdded(ServletContextAttributeEvent arg0) { System.out.println("属性被加进来"+arg0.getName()+arg0.getValue()); } public void attributeRemoved(ServletContextAttributeEvent arg0) { System.out.println("属性被移除"+arg0.getName()+arg0.getValue()); } public void attributeReplaced(ServletContextAttributeEvent arg0) { System.out.println("属性被替换"+arg0.getName()+arg0.getValue()); } }
3.使javabean自己感知自己在Session中状态变化的监听器,这两个监听器很特殊,不需要自己去写类实现也不需要在web.xml中注册,只要使javabean实现这个接口就能起作用
HttpSessionBindingListener
javabean被绑定到session中
sessionDidActive(HttpSessionBindingEvent event)
javabean被移除绑定从session中
valueUnbound(HttpSessionBindingEvent event)方法
HttpSessionActivationListener
javabean随着session被钝化
sessionWillPassivate(HttpSessionBindingEvent event)
javabean随着session被活化
sessionDidActive(HttpSessionBindingEvent event)
package com.dzq.domain; import java.io.Serializable; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionEvent; public class Person implements Serializable ,HttpSessionBindingListener,HttpSessionActivationListener{ private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public void valueBound(HttpSessionBindingEvent arg0) { System.out.println("当前javabean对象被绑定到session域中时,javabean自己感知到自己被绑定,触发此方法"); } @Override public void valueUnbound(HttpSessionBindingEvent arg0) { System.out.println("当前javabean对象被移除session域中时,javabean自己感知到自己被解绑,触发此方法"); } //感知被钝化与活化 @Override public void sessionDidActivate(HttpSessionEvent arg0) { System.out.println("javabean自己感知到自己被活化,触发此方法"); } @Override public void sessionWillPassivate(HttpSessionEvent arg0) { System.out.println("javabean自己感知到自己被钝化,触发此方法"); } }
踢人小案例:
建立数据库:
package com.dzq.domain; import java.io.Serializable; import java.util.Map; import javax.print.attribute.standard.Severity; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; public class User implements Serializable,HttpSessionBindingListener{ private int id; private String name; private String password; private String role; public int getId() { return id; } public void setId(int id) { this.id = id; } 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; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } @Override public void valueBound(HttpSessionBindingEvent event) { //当用户登录时,bean存入session中,向用户列表添加信息 HttpSession session=event.getSession(); ServletContext context= session.getServletContext(); Map<User,HttpSession> map=(Map<User, HttpSession>) context.getAttribute("usermap"); map.put(this, session); } @Override public void valueUnbound(HttpSessionBindingEvent event) { //当用户下线时,bean移除session中,向用户列表移除信息 HttpSession session=event.getSession(); ServletContext context= session.getServletContext(); Map<User,HttpSession> map=(Map<User, HttpSession>) context.getAttribute("usermap"); map.remove(this, session); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
package com.dzq.listener; import java.util.*; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import com.dzq.domain.User; @WebListener public class MySCListener implements ServletContextListener { public void contextDestroyed(ServletContextEvent sce) { } public void contextInitialized(ServletContextEvent sce) { ServletContext context=sce.getServletContext(); context.setAttribute("usermap", new LinkedHashMap<User, HttpSession>()); } }
package com.dzq.utils; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DaoUtils { private static DataSource source=new ComboPooledDataSource(); private DaoUtils(){ } public static DataSource getSource(){ return source; } public static Connection getConnection(){ try { return source.getConnection(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } }
package com.dzq.web; import java.io.IOException; import java.sql.SQLException; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import com.dzq.domain.User; import com.dzq.utils.DaoUtils; @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String name=request.getParameter("name"); String password=request.getParameter("password"); String sql="select * from user where name=? and password =?"; User user=new User(); QueryRunner runner=new QueryRunner(DaoUtils.getSource()); try { user=runner.query(sql, new BeanHandler<User>(User.class),name,password); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } if(user==null){ response.getWriter().write("用户名密码不正确"); }else{ ServletContext context=this.getServletContext(); Map<User,HttpSession> map=(Map<User, HttpSession>) context.getAttribute("usermap"); HttpSession session=map.get(user); if(session!=null) session.invalidate(); request.getSession().setAttribute("user", user); response.sendRedirect(request.getContextPath()+"/index.jsp"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.dzq.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/LogOutServlet") public class LogOutServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if(request.getSession(false)!=null){ request.getSession().invalidate(); } response.sendRedirect(request.getContextPath()+"/index.jsp"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.dzq.web; import java.io.IOException; import java.sql.SQLException; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import com.dzq.domain.User; import com.dzq.utils.DaoUtils; @WebServlet("/KickServlet") public class KickServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取用户id String id=request.getParameter("id"); User user=null; //根据id查询用户 String sql="select * from user where id =?"; QueryRunner runner=new QueryRunner(DaoUtils.getSource()); try { user=runner.query(sql, new BeanHandler<User>(User.class),id); ServletContext context=this.getServletContext(); Map<User,HttpSession> map=(Map<User, HttpSession>) context.getAttribute("usermap"); HttpSession session=map.get(user); if(session!=null) session.invalidate(); response.sendRedirect(request.getContextPath()+"/userlist.jsp"); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } //找到session //杀死session } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
<?xml version="1.0" encoding="utf-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/0417?Unicode=true&characterEncoding=utf-8</property> <property name="user">root</property> <property name="password"></property> </default-config> </c3p0-config>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>踢人管理</title> </head> <body> <div align="center"> <h1>踢人管理系统</h1><hr> <c:if test="${sessionScope.user==null }"> <a href="${pageContext.request.contextPath }/login.jsp">请登录</a> </c:if> <c:if test="${sessionScope.user!=null }"> 欢迎回来,${sessionScope.user.name } <a href="${pageContext.request.contextPath }/userlist.jsp">用户列表</a> <a href="${pageContext.request.contextPath}/LogOutServlet">注销</a> </c:if> </div> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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>踢人管理</title> </head> <body> <div align="center"> <h1>踢人管理_用户登录</h1><hr> <form action="${pageContext.request.contextPath }/LoginServlet" method="post"> 用户名:<input type="text" name="name"/> 密码:<input type="password" name="password"/> <input type="submit" value="登录"/> </form> </div> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>踢人管理系统</title> </head> <body> <div align="center"> <h1>踢人管理_用户列表</h1><hr> <c:forEach items="${applicationScope.usermap }" var="entry"> ${entry.key.name }<br> <c:if test="${sessionScope.user.role=='admin' }"> <a href="${pageContext.request.contextPath }/KickServlet?id=${entry.key.id}">去死吧</a> </c:if> </c:forEach> </div> </body> </html>
工程结构:
源工程下载: