Java监听器

image.png

监听器

  • web应用服务器通过监听器来监听servlet和与之对应的jsp中的三个内置对象。
  • web监听器本身是servlet规范定义的一种特殊类
  • 用于监听ServletContext、HttpSession、ServletRequest等域对象的创建、销毁、及其属性修改变化发生的事件
  • 监听器可以在事件发生前后进行一些必要的处理操作

常见应用场景

  • 统计在线人数
  • 页面访问量统计
  • 应用启动时完成信息初始化工作
  • 与spring结合

监听器实现步骤

1、编写Java类实现监听器接口,并实现其接口方法。
2、在web.xml文件中对实现的监听器类进行注册。



监听器按监听事件分类

  • 域对象自身的创建和销毁事件监听器
  • 域对象中属性的创建、替换和消除事件监听器
  • 绑定到session中的某个对象的状态事件监听器

ServletContextListener

image.png
  • 案例
    servlet3.0可以不必在web.xml中配置 程序中有注解@WebListener
package com.alan.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;


@WebListener
public class MyServletContextListener implements ServletContextListener {


    public MyServletContextListener() {
    }



    public void contextDestroyed(ServletContextEvent sce)  { 
        
        //在ServletContext对象中获取域中的值
        String appName = (String) sce.getServletContext().getAttribute("app_name");
        String version = (String) sce.getServletContext().getAttribute("version");
 
        
        //打印输出
        System.out.println("appName="+appName);
        System.out.println("version="+version);
        
    }



    public void contextInitialized(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
        
        //从web.xml获得初始化参数
        String appName = sce.getServletContext().getInitParameter("app_name");
        String version = sce.getServletContext().getInitParameter("version");
        
        
        //将参数赋值到ServletContext作用域中
        sce.getServletContext().setAttribute("app_name", appName);
        sce.getServletContext().setAttribute("version", version);
        
        //打印输出
        System.out.println("appName="+appName);
        System.out.println("version="+version);
        
    }
    
}


  ListenerDemoWebProj
  
    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp
  
  
  
    app_name
    Listener Web
  
  
  
    version
    1.0
  
  
  
    com.alan.listener.MyServletContextListener
  
  


SessionListener

  • 每一个浏览器就会创建一个session
  • MyServletContextListener
package com.alan.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;


@WebListener
public class MyServletContextListener implements ServletContextListener {


    public MyServletContextListener() {
    }



    public void contextDestroyed(ServletContextEvent sce)  { 
        
        //在ServletContext对象中获取域中的值
        String appName = (String) sce.getServletContext().getAttribute("app_name");
        String version = (String) sce.getServletContext().getAttribute("version");
 
        
        //打印输出
        System.out.println("appName="+appName);
        System.out.println("version="+version);
        
    }



    public void contextInitialized(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
        
        //从web.xml获得初始化参数
        String appName = sce.getServletContext().getInitParameter("app_name");
        String version = sce.getServletContext().getInitParameter("version");
        
        
        //将参数赋值到ServletContext作用域中
        sce.getServletContext().setAttribute("app_name", appName);
        sce.getServletContext().setAttribute("version", version);
        
        //打印输出
        System.out.println("appName="+appName);
        System.out.println("version="+version);
        
    }
    
}
  • web.xml
  
  
  1
  
  • 效果图



ServletRequestListener

package com.alan.listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;


@WebListener
public class MyServletRequestListener implements ServletRequestListener {



    public MyServletRequestListener() {
        // TODO Auto-generated constructor stub
    }


    public void requestDestroyed(ServletRequestEvent sre)  { 

        System.out.println("request listener destroyed...");
    }



    public void requestInitialized(ServletRequestEvent sre)  { 
        
        //向下转型
        HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();
        
        //获得请求路径和请求参数
        String path = request.getRequestURI();
        String par = request.getParameter("par");
        
        System.out.println("request listener path:"+path+",par:"+par);

    }
    
}

ServletContextAttributeListener

image.png
package com.alan.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;


@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {


    public MyServletContextAttributeListener() {
        // TODO Auto-generated constructor stub
    }


    public void attributeAdded(ServletContextAttributeEvent scae)  { 

        System.out.println("attributeAdded   name:"+scae.getName()+",value:"+scae.getValue());
    
    }


    public void attributeRemoved(ServletContextAttributeEvent scae)  { 
        System.out.println("attributeRemoved   name:"+scae.getName()+",value:"+scae.getValue());
    }


    public void attributeReplaced(ServletContextAttributeEvent scae)  { 
        System.out.println("attributeReplaced   name:"+scae.getName()+",value:"+scae.getValue());
    }
    
}

HttpSessionBindingListener

  • 不需要在web.xml中注册,即可使用
package com.alan.model;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;


//@WebListener
public class User implements HttpSessionBindingListener {

    private String username ;
    private String passowrd;
    
    
    public User() {
        // TODO Auto-generated constructor stub
    }


    public void valueBound(HttpSessionBindingEvent hsbe)  { 

        String name = hsbe.getName();
        System.out.println("valueBound   name:"+name);
    }


    public void valueUnbound(HttpSessionBindingEvent hsbe)  { 
            
        String name = hsbe.getName();
        System.out.println("valueUnbound   name:"+name);
    }


    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username;
    }


    public String getPassowrd() {
        return passowrd;
    }


    public void setPassowrd(String passowrd) {
        this.passowrd = passowrd;
    }
    
    
    
}

实际案例

实现登陆用户不能重复登陆的功能
1、实现登陆功能
2、登陆权限过滤器验证
3、用户信息存储实现
4、监听功能实现
项目存放在 LoginListenerWebProj

  • 监听核心代码
package com.alan.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

import com.alan.cache.LoginCache;


@WebListener
public class LoginSessionListener implements HttpSessionAttributeListener {
    
    //定义常量方便操作
    private static final String LOGIN_USER = "loginUser";


    public LoginSessionListener() {


    }


    public void attributeAdded(HttpSessionBindingEvent hsbe)  { 
        String attrName = hsbe.getName();
        //session中有可能有很多的定义的属性,需要判断是否为需要的loginUser
        if(LOGIN_USER.equals(attrName)) {
            //获取属性值、session、sessionId.
            String value = (String)hsbe.getValue();
            HttpSession session = hsbe.getSession();
            String sessionId = session.getId();
            //获取缓存中的sessionId判断是否登陆过
            String sessionIdInCache = LoginCache.getLoginCache().getSessionIdByLoginName(value);
            //如果sessionInCache为空,说明当前用户没有登陆过
            if(sessionIdInCache==null) {
                LoginCache.getLoginCache().setSessionIdByLoginName(value, sessionId);
                LoginCache.getLoginCache().setSessionBySessionId(sessionId, session);
            }else {
                //已经存在的话,取到原来的session将其销毁
                HttpSession sessionInCache = LoginCache.getLoginCache().getSessionBySessionId(sessionIdInCache);
                sessionInCache.invalidate();
                //将新的session覆盖到map集合中
                LoginCache.getLoginCache().setSessionIdByLoginName(value, sessionId);
                LoginCache.getLoginCache().setSessionBySessionId(sessionId, session);
            }
            
            

        }

    }


    public void attributeRemoved(HttpSessionBindingEvent hsbe)  { 


    }



    public void attributeReplaced(HttpSessionBindingEvent hsbe)  { 


    }
    
}
  • 单例模式cache创建
package com.alan.cache;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;

public class LoginCache {

    //单例模式实现
    //创建用户名与sessionId的键值对
    private Map loginUserSession = new HashMap<>();
    //创建sessionId与session对象的键值对
    private Map loginSession = new HashMap<>();
    
    //1、构造函数私有化
    private LoginCache() {
        
    }
    //2、将对象私有静态实例化
    private static LoginCache instance = new LoginCache();

    //3、通过公有静态方法返回该对象
    public static LoginCache getLoginCache() {
        return instance;
    }

    //方法:根据用户名返回对应的sessionId
    public String getSessionIdByLoginName(String LoginName) {
        return loginUserSession.get(LoginName);
    }
    //方法:根据sessionId返回对应的session对象
    public HttpSession getSessionBySessionId(String sessionId) {
        return loginSession.get(sessionId);
    }
    //方法:将用户名和sessionId存入map集合中
    public void setSessionIdByLoginName(String loginName,String sessionId) {
        loginUserSession.put(loginName, sessionId);
    }
    //方法:将sessionId和session对象存入map集合中
    public void setSessionBySessionId(String sessionId,HttpSession session ) {
        loginSession.put(sessionId, session);
    }
    
}

你可能感兴趣的:(Java监听器)