监听器(Listener)

概述

监听器(listener): 
主要是用来监听特定对象的创建或销毁、属性的变化的!
是一个实现特定接口的普通java类!

对象:
自己创建自己用 (不用监听)
别人创建自己用 (需要监听)

Servlet中哪些对象需要监听?
request / session / servletContext
分别对应的是request监听器、session相关监听器、servletContext监听器

监听器接口:
一、监听对象创建/销毁的监听器接口
Interface ServletRequestListener     监听request对象的创建或销毁
Interface HttpSessionListener        监听session对象的创建或销毁
Interface ServletContextListener     监听servletContext对象的创建或销毁
二、监听对象属性的变化
Interface ServletRequestAttributeListener 监听request对象属性变化: 添加、移除、修改
Interface HttpSessionAttributeListener    监听session对象属性变化: 添加、移除、修改
Interface ServletContextAttributeListener  监听servletContext对象属性变化

三、session相关监听器
Interface HttpSessionBindingListener   监听对象绑定到session上的事件
Interface HttpSessionActivationListener(了解) 监听session序列化及反序列化的事件

生命周期监听器

生命周期监听器: 监听对象的创建、销毁的过程!
监听器开发步骤:
1.写一个普通java类,实现相关接口;
2.配置(web.xml)

ServletRequestListener

监听器类
   
   
  1. package com.cn.life;
  2. import javax.servlet.ServletRequestEvent;
  3. import javax.servlet.ServletRequestListener;
  4. import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
  5. /**
  6. * 监听request对象的创建或销毁
  7. * @author liuzhiyong
  8. *
  9. */
  10. public class MyServletRequestListener implements ServletRequestListener {
  11. /**
  12. * 对象销毁
  13. */
  14. @Override
  15. public void requestDestroyed(ServletRequestEvent sre) {
  16. //获取request中存放的数据
  17. Object att = sre.getServletRequest().getAttribute("attr1");
  18. System.out.println(att);
  19. System.out.println("MyServletRequestListener.requestDestroyed()");
  20. }
  21. /**
  22. * 对象创建
  23. */
  24. @Override
  25. public void requestInitialized(ServletRequestEvent sre) {
  26. System.out.println("MyServletRequestListener.requestInitialized()");
  27. }
  28. }
web.xml配置
   
   
  1. <!-- 监听request对象创建、销毁 -->
  2. <listener>
  3. <listener-class>com.cn.life.MyServletRequestListener</listener-class>
  4. </listener>

ServletContextListener

监听器类
    
    
  1. package com.cn.life;
  2. import javax.servlet.ServletContextEvent;
  3. import javax.servlet.ServletContextListener;
  4. public class MyServletContextListener implements ServletContextListener {
  5. /**
  6. * 创建时
  7. */
  8. @Override
  9. public void contextInitialized(ServletContextEvent sce) {
  10. System.out.println("................................MyServletContextListener.contextInitialized()");
  11. }
  12. /**
  13. * 销毁时
  14. */
  15. @Override
  16. public void contextDestroyed(ServletContextEvent sce) {
  17. System.out.println("................................MyServletContextListener.contextDestroyed()");
  18. }
  19. }
web.xml配置
     
     
  1. <!-- 监听ServletContext对象创建、销毁 -->
  2. <listener>
  3. <listener-class>com.cn.life.MyServletContextListener</listener-class>
  4. </listener>

HttpSessionListener

监听器类
    
    
  1. package com.cn.life;
  2. import javax.servlet.http.HttpSessionEvent;
  3. import javax.servlet.http.HttpSessionListener;
  4. public class MyHttpSessionListener implements HttpSessionListener {
  5. /**
  6. * 创建
  7. */
  8. @Override
  9. public void sessionCreated(HttpSessionEvent se) {
  10. System.out.println("MyHttpSessionListener.sessionCreated()");
  11. }
  12. /**
  13. * 销毁
  14. */
  15. @Override
  16. public void sessionDestroyed(HttpSessionEvent se) {
  17. System.out.println("MyHttpSessionListener.sessionDestroyed()");
  18. }
  19. }
web.xml配置
   
   
  1. <!-- 监听Session对象创建、销毁 -->
  2. <listener>
  3. <listener-class>com.cn.life.MyHttpSessionListener</listener-class>
  4. </listener>

属性监听器

属性监听器: 监听属性的变化!
监听器开发步骤:
1.写一个普通java类,实现相关接口;
2.配置(web.xml)

ServletRequestAttributeListener

监听器类
   
   
  1. package com.cn.attribute;
  2. import javax.servlet.ServletRequestAttributeEvent;
  3. import javax.servlet.ServletRequestAttributeListener;
  4. /**
  5. * 监听request属性
  6. * @author liuzhiyong
  7. *
  8. */
  9. public class MyServletRequestAttributeListener implements
  10. ServletRequestAttributeListener {
  11. @Override
  12. public void attributeAdded(ServletRequestAttributeEvent srae) {
  13. System.out
  14. .println("MyServletRequestAttributeListener.attributeAdded()");
  15. System.out.println("获取添加的属性值" + srae.getServletRequest().getAttribute("attr1"));
  16. }
  17. @Override
  18. public void attributeRemoved(ServletRequestAttributeEvent srae) {
  19. System.out
  20. .println("MyServletRequestAttributeListener.attributeRemoved()");
  21. }
  22. @Override
  23. public void attributeReplaced(ServletRequestAttributeEvent srae) {
  24. System.out
  25. .println("MyServletRequestAttributeListener.attributeReplaced()");
  26. }
  27. }
web.xml配置
   
   
  1. <!-- 监听request属性 -->
  2. <listener>
  3. <listener-class>com.cn.attribute.MyServletRequestAttributeListener</listener-class>
  4. </listener>

HttpSessionAttributeListener

监听器类
    
    
  1. package com.cn.attribute;
  2. import javax.servlet.http.HttpSession;
  3. import javax.servlet.http.HttpSessionAttributeListener;
  4. import javax.servlet.http.HttpSessionBindingEvent;
  5. public class MyHttpSessionAttributeListener implements
  6. HttpSessionAttributeListener {
  7. @Override
  8. public void attributeAdded(HttpSessionBindingEvent se) {
  9. System.out.println("添加session属性值" + se.getSession().getAttribute("attr2"));
  10. System.out.println("MyHttpSessionAttributeListener.attributeAdded()");
  11. }
  12. @Override
  13. public void attributeRemoved(HttpSessionBindingEvent se) {
  14. System.out.println("移除session属性值" + se.getSession().getAttribute("attr2"));
  15. System.out.println("MyHttpSessionAttributeListener.attributeRemoved()");
  16. }
  17. @Override
  18. public void attributeReplaced(HttpSessionBindingEvent se) {
  19. //获取session对象
  20. HttpSession session = se.getSession();
  21. //获取替换前的值
  22. Object oldValue = se.getValue();
  23. System.out.println("session原来的属性值" + oldValue);
  24. //获取新值
  25. Object newValue = session.getAttribute("attr2");
  26. System.out.println("session新的属性值" + newValue);
  27. }
  28. }
web.xml配置
    
    
  1. <!-- 监听session属性 -->
  2. <listener>
  3. <listener-class>com.cn.attribute.MyHttpSessionAttributeListener</listener-class>
  4. </listener>

其他监听器:session相关监听器

HttpSessionBindingListener   

监听对象绑定/解除绑定到sesison上的事件!
步骤:
对象实现接口; 再把对象绑定/解除绑定到session上就会触发监听代码。
作用:
(上线提醒!)
       思考:这个session监听器,和上面的声明周期、属性监听器区别?
               不用再web.xml配置,因为监听的对象是自己创建的对象,不是服务器对象!
   
   
  1. package com.cn.session;
  2. import javax.servlet.http.HttpSession;
  3. import javax.servlet.http.HttpSessionBindingEvent;
  4. import javax.servlet.http.HttpSessionBindingListener;
  5. /**
  6. * 监听此对象绑定到session上的过程,需要实现特定接口HttpSessionBindingListener
  7. * @author liuzhiyong
  8. *
  9. */
  10. public class User implements HttpSessionBindingListener{
  11. private int id;
  12. private String userName;
  13. private String pwd;
  14. public int getId() {
  15. return id;
  16. }
  17. public void setId(int id) {
  18. this.id = id;
  19. }
  20. public String getUserName() {
  21. return userName;
  22. }
  23. public void setUserName(String userName) {
  24. this.userName = userName;
  25. }
  26. public String getPwd() {
  27. return pwd;
  28. }
  29. public void setPwd(String pwd) {
  30. this.pwd = pwd;
  31. }
  32. public User() {
  33. }
  34. public User(int id, String userName, String pwd) {
  35. super();
  36. this.id = id;
  37. this.userName = userName;
  38. this.pwd = pwd;
  39. }
  40. /**
  41. * 对象放入session
  42. */
  43. @Override
  44. public void valueBound(HttpSessionBindingEvent event) {
  45. HttpSession session = event.getSession();
  46. System.out.println("对象放入session中");
  47. }
  48. /**
  49. * 对象从session中移除
  50. */
  51. @Override
  52. public void valueUnbound(HttpSessionBindingEvent event) {
  53. System.out.println("对象从session中移除");
  54. }
  55. }

案例

需求:

       做一个在线列表提醒的功能!
      用户 -> 登陆
   -> 显示登陆信息,列表展示。(list.jsp)
   -> 显示在线用户列表        (list.jsp)
   -> 列表点击进入“在线列表页面”   onlineUser.jsp

实现思路:

1.写监听器,监听servletContext对象的创建: 初始化集合(onlineUserList)
2.登陆功能:用户登陆时候,把数据保存到servletContext中
3.退出功能: 销毁当前session
3 .写监听器:监听session销毁,把当前登陆用户从onlineUserList移除!
4.list.jsp  增加超链接, 点击时候提交直接跳转到onlineUserList.jsp

核心代码:

监听servletContext对象的创建: 初始化在线列表集合(onlineuserlist)
   
   
  1. package com.cn.listener;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.servlet.ServletContext;
  5. import javax.servlet.ServletContextEvent;
  6. import javax.servlet.ServletContextListener;
  7. import com.cn.entity.User;
  8. /**
  9. * 监听servletContext对象的创建: 初始化在线列表集合(onlineuserlist)
  10. * @author liuzhiyong
  11. *
  12. */
  13. public class OnlineUserListener implements ServletContextListener {
  14. /**
  15. * 监听servletContext对象的创建
  16. */
  17. @Override
  18. public void contextInitialized(ServletContextEvent sce) {
  19. /**
  20. * 创建集合,存放在线用户
  21. * 每次当用户登陆后,就往这个集合中添加当前登陆者
  22. */
  23. List<User> onlineUserList = new ArrayList<User>();
  24. //放入servletContext中
  25. sce.getServletContext().setAttribute("onlineUserList", onlineUserList);
  26. }
  27. /**
  28. * 监听servletContext对象的销毁
  29. */
  30. @Override
  31. public void contextDestroyed(ServletContextEvent sce) {
  32. //获取ServletContext
  33. ServletContext sc = sce.getServletContext();
  34. //获取在线列表
  35. Object obj = sc.getAttribute("onlineList");
  36. //移除在线刘表集合
  37. if(obj != null){
  38. sc.removeAttribute("onlineList");
  39. }
  40. }
  41. }
登陆功能:用户登陆时候,把数据保存到servletContext中
   
   
  1. package com.cn.servlet;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.servlet.ServletContext;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import com.cn.entity.User;
  11. import com.cn.service.UserService;
  12. import com.cn.service.impl.UserServiceImpl;
  13. /**
  14. * 登录控制层
  15. * @author liuzhiyong
  16. *
  17. */
  18. public class LoginServlet extends HttpServlet {
  19. //Service实例
  20. private UserService service = new UserServiceImpl();
  21. //跳转资源
  22. private String uri;
  23. public void doGet(HttpServletRequest request, HttpServletResponse response)
  24. throws ServletException, IOException {
  25. try {
  26. //获取请求参数
  27. String email = request.getParameter("email");
  28. String pwd = request.getParameter("pwd");
  29. //封装
  30. User user = new User();
  31. user.setEmail(email);
  32. user.setPwd(pwd);
  33. //调用Service处理业务
  34. User userInfo = service.findByEmailAndPwd(user);
  35. //判断
  36. if(userInfo!= null){
  37. /*
  38. * 登录成功
  39. */
  40. //保存登录数据到session
  41. request.getSession().setAttribute("userInfo", userInfo);
  42. /**
  43. * 在线列表功能:
  44. * 1.先从ServletContext中获取在线列表集合(onlineList)
  45. * 2.用户登陆时候,把当前用户数据保存到“在线列表集合”中
  46. */
  47. //得到servletContext对象
  48. ServletContext sc = request.getServletContext();
  49. //获取在线列表集合
  50. List<User> onlineUserList = (ArrayList<User>)sc.getAttribute("onlineUserList");
  51. //添加当前登录者
  52. onlineUserList.add(userInfo);
  53. //保存当前登录者到ServletContext中
  54. // sc.setAttribute("onlineUserList", onlineUserList);//这里可以不写,因为对象引用传递
  55. //跳转到首页Servlet
  56. uri = "/ListServlet";
  57. }else{
  58. /**
  59. * 登录失败
  60. */
  61. //将用户输入的数据放入request域对象中
  62. request.setAttribute("email", email);
  63. //保存提示信息到request域对象中
  64. request.setAttribute("msg", "密码或账号错误!");
  65. //转发到登录页面
  66. uri = "/login.jsp";
  67. }
  68. } catch (Exception e) {
  69. //测试
  70. e.printStackTrace();
  71. //错误页面
  72. uri = "/error/error.jsp";
  73. }
  74. //跳转
  75. request.getRequestDispatcher(uri).forward(request, response);
  76. }
  77. public void doPost(HttpServletRequest request, HttpServletResponse response)
  78. throws ServletException, IOException {
  79. this.doGet(request, response);
  80. }
  81. }
退出功能:当前session销毁
   
   
  1. package com.cn.servlet;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.servlet.ServletContext;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import javax.servlet.http.HttpSession;
  11. import com.cn.entity.User;
  12. /**
  13. * 退出功能:当前session销毁
  14. * @author liuzhiyong
  15. *
  16. */
  17. public class OutServlet extends HttpServlet {
  18. public void doGet(HttpServletRequest request, HttpServletResponse response)
  19. throws ServletException, IOException {
  20. //获取当前用户session中当前用户的信息
  21. HttpSession session = request.getSession(false);
  22. User userInfo = (User)session.getAttribute("userInfo");
  23. //移除session中属性为“userInfo”的用户信息
  24. // session.removeAttribute("userInfo");//这里不删,因为监听器中需要获取,不能删,只用销毁session了,就能调用session监听器
  25. //销毁session
  26. session.invalidate();
  27. //跳转到登录页
  28. response.sendRedirect(request.getContextPath()+"/login.jsp");
  29. }
  30. public void doPost(HttpServletRequest request, HttpServletResponse response)
  31. throws ServletException, IOException {
  32. this.doPost(request, response);
  33. }
  34. }
写监听器:监听session销毁,把当前登陆用户从onlineUserList移除!
   
   
  1. package com.cn.listener;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.servlet.ServletContext;
  5. import javax.servlet.http.HttpSession;
  6. import javax.servlet.http.HttpSessionEvent;
  7. import javax.servlet.http.HttpSessionListener;
  8. import com.cn.entity.User;
  9. /**
  10. * 监听服务器session销毁的动作:session.invalid();
  11. * 当session销毁的时候,从在线列表集合中移除当前的登录用户
  12. * @author liuzhiyong
  13. *
  14. */
  15. public class SessionInvalidListener implements HttpSessionListener {
  16. @Override
  17. public void sessionCreated(HttpSessionEvent se) {
  18. // TODO Auto-generated method stub
  19. }
  20. @Override
  21. public void sessionDestroyed(HttpSessionEvent se) {
  22. System.out.println("。。。。。。。。。。。。。。。。。。。。。。session销毁一个。。。。。。。。。。。。。。。。。。。");
  23. //获取当前销毁的session对象
  24. HttpSession session = se.getSession();
  25. //获取session中userInfo的属性
  26. User userInfo = (User)session.getAttribute("userInfo");
  27. //获取ServletContext对象
  28. ServletContext sc = session.getServletContext();
  29. //获取ServletContext中的在线用户列表
  30. List<User> onlineUserList = (ArrayList<User>)sc.getAttribute("onlineUserList");
  31. //删除当前登录者
  32. if(userInfo != null){
  33. onlineUserList.remove(userInfo);
  34. }
  35. //保存当前登录者到ServletContext中
  36. // sc.setAttribute("onlineUserList", onlineUserList);//这里可以不写,因为对象引用传递
  37. }
  38. }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值