listener知识点以及应用

8 篇文章 0 订阅

Servlet监听器Listener

  • Servlet监听器的概念

用于监听ServletContext、HttpSession和ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中属性发生修改的事件。
监听对象:
1、ServletContext:application,整个应用只存在一个
2、HttpSession:session,针对每一个对话
3、ServletRequest:request,针对每一个客户请求
监听内容:创建、销毁、属性改变事件
监听作用:可以在事件发生前、发生后进行一些处理,一般可以用来统计在线人数和在线用户、统计网站访问量、系统启动时初始化信息等。

  • 监听器的基本使用

创建步骤:
1、创建一个实现监听器接口的类
2、配置web.xml文件,注册监听器
<listener>
<listener-class>完整类名</listener-class>
</listener>
监听器的启动顺序:按照web.xml的配置顺序来启动
加载顺序:监听器>过滤器>Servlet

  • 监听器的分类

  • a 按照监听的对象划分
    用于监听应用程序环境对象(ServletContext)的事件监听器,实现ServletContextListener、ServletContextAttributeListener接口
    用于监听用户会话对象(HttpSeesion)的事件监听器,实现HttpSessionListener、HttpSessionAttributeListener接口
    用于监听请求消息对象(ServletRequest)的事件监听器,实现ServletRequestListener、ServletRequestAttributeListener接口
    b 按照监听事件划分
    1、监听域对象自身的创建和销毁的事件监听器
    根据监听对象不同分别实现ServletContextListener、HttpSessionListener、ServletRequestListener接口。
    ①ServletContext的创建和销毁:contextInitialized方法和contextDestroyed方法
    public void contextInitialized(ServletContextEvent sce)//ServletContext创建时调用
    public void contextDestroyed(ServletContextEvent sce)//ServletContext销毁时调用
    主要用途:作为定时器、加载全局属性对象、创建全局数据库连接、加载缓存信息等
    实例:
    在web.xml中可以配置项目初始化信息,在contextInitialized方法中进行启动
<context-param>
    <param-name>属性名</param-name>
    <param-value>属性值</param-value>
</context-param>

自定义监听器

public class MyFirstListener implements ServletContextListener{
    public void contextInitialized(ServletContextEvent sce){
        //获取web.xml中配置的属性
        String value=sce.getServletContext().getInitParameter("属性名");
        System.out.println(value);
  }
    public void contextDestroyed(ServletContextEvent sce){
        //关闭时操作
  }
}

②HttpSession的创建和销毁:sessionCreated和sessionDestroyed方法
public void sessionCreated(HttpSessionEvent se)//session创建时调用
public void sessionDestroyed(HttpSessionEvent se)//session销毁时调用
主要用途:统计在线人数、记录访问日志等
【注】
web.xml配置session超时参数,单位:分,session超时的时间并不是精确的

<session-config>
    <session-timeout>10</session-timeout>
</session-config>

③ServletRequest的创建和销毁:requestInitialized和requestDestroyed方法
public void requestInitialized(ServletRequestEvent sre)//request创建时调用
public void requestDestroyed(ServletRequestEvent sre)//request销毁时调用
主要用途:读取request参数,记录访问历史
实例:

public class MySRequestListener implements SevletRequestListener{
    public void requestInitialized(ServletRequestEvent sre){
        String value=sre.getServletRequest().getParameter("key");//获取request中的参数
        System.out.println(value);
    }
    public void requestDestroyed(ServletRequestEvent sre){  
        System.out.println("request destroyed");
    }
}   
 

2、监听域对象中的属性的增加和删除的事件监听器
  根据监听对象不同分别实现ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener接口。
  实现方法:attributeAdded、attributeRemoved、attributeReplaced

3、监听绑定到HttpSeesion域中的某个对象的状态的事件监听器(创建普通JavaBean)
  HttpSession中的对象状态:绑定→解除绑定;钝化→活化
 实现接口及方法:HttpSessionBindingListener接口(valueBound和valueUnbound方法)、HttpSessionActivationListener接口(sessionWillPassivate和sessionDidActivate方法)
【注1】①要实现钝化和活化必须实现Serializable接口
            ②不需要在web.xml中注册
【注2】
  绑定:    通过setAttribute保存到session对象当中
  解除绑定:  通过removeAttribue去除
  钝化:    将session对象持久化到存储设备上
  活化:    将session对象从存储设备上进行恢复
  session钝化机制:
    ①把服务器不常使用的session对象暂时序列化到系统文件或者是数据库中,当使用时反序列化到内存中,整个过程由服务器自动完成;
   ②session的钝化机制由SessionManager管理,创建一个普通的JavaBean绑定和接触需要实现HttpSessionBindingListener接口

使用注解

@WebListener的常用属性

属性名类型是否可选描述
valueString该监听器的描述信息

@WebListener(“This is a listener”)
public class FirstListener impliements ServletRequestListener{}
该注解用于将类声明为监听器,被 @WebListener 标注的类必须实现以下至少一个接口:
  ServletContextListener
  ServletContextAttributeListener
  ServletRequestListener
  ServletRequestAttributeListener
  HttpSessionListener
  HttpSessionAttributeListener

HttpSessionBindingListener和HttpSessionAttributeListener

1.BindingListener有2个方法,valueBound(HttpSessinBindingEvent)和valueUnbount(HttpSessionBindingEvent)。实现BindingListener接口的对象被绑 定到session时触发valueBound事件,解除绑定时触发valueUnbound事件。举例来说:

public class UserObject implements HttpSessionBindingListener{      
    public void valueBound(HttpSessionBindingEvent event){          
       System.out.println("触发绑定事件!");      
      }      
    public void valueUnbound(HttpSessionBindingEvent event){          
       System.out.println("解除和session的绑定");      
   }  

UserObject user = new UserObject();
当把该监听器保存到session中,session.setAttribute(“user”,user)时就会触发valueBound事件.
当该监听器从session中移除时即session.removeAttribute(“user”),触发valueUnbound事件;session失效或超时
时也会触发valueUnbound事件。
注意:只有当该监听器(UserObject)保存到session中或从session移除时才会触发事件,其他没有实现该listener对象保存到session时不会触发该事件。
2.AttributeListener接口有3方法,attributeAdded(HttpSessionBindingEvent),attributeRemoved(HttpSessionBindingEvent),
attributeReplaced(HttpSeesionEvent)。当在session中添加、移除或更改属性值时会触发相应的事件。

	MyListener implements HttpSessionAttributeListener{      
	    attributeAdded(HttpSessionBindingEvenet event){          
	        System.out.println("有对象加入session中");      
	        }       
	    attributeRemoved(HttpSessionBindingEvent event){           
	        System.out.println("有对象从session中移除");       
	        }       
	    attributeReplaced(HttpSessionBindingEvent event){            
        System.out.println("属性值改变");        
	        }  
	    }  

OtherObject other = new OtherObject();
当有对象添加到session中时,session.setAttribute(“object”,other)触发attributeAdded事件,
当该对象从session移除时,session.removeAttribute(“object”)触发attriubteRemoved事件,
当该属性的值发生变化时, session.replaceAttribute(“object”,another)触发attributeRepalced事件。
注意:只要有对象保存到session中或从session中移除或改变属性的值都会触发相应事件,不论该对象是否实现了AttributeListener。

总结:
1.只有实现了HttpSessionBindingListener的类,在和session绑定、解除绑定时触发其事件。
2.实现了HttpSessionAttributeListener后,任何对象(不论其是否实现了AttributeListener)在变化时均触发对应的事件。

HttpSessionActivationListener监听session对象的序列化与反序列化

HttpSessionActivationListener用于监控实现类本身,当实现类对象被添加到session中(session.setAttribute())后,session对象序列化(钝化)前和反序列化(活化)后都会被执行,相应的方法。

• sessionWillPassivate(HttpSessionEvent se) session钝化前执行(session从内存到硬盘)
• sessionDidActivate(HttpSessionEvent se) session活化后执行(session从硬盘到内存)
2.我们通过在META-INF目录下配置context.xml文件,设置失效时间和session序列化的保存路径,配置如下:

 <Context>
   <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
     <Store className="org.apache.catalina.session.FileStore" directory="d:/session"/>
   </Manager>
 </Context>

• maxIdlSwap="1"表示失效时间为1分钟
• directory="d:/session"是session保存路径
然后定义一个类实现HttpSessionActivationListener接口,监听session的序列化

public class ListenerTest implements HttpSessionActivationListener,Serializable {
      private static final long serialVersionUID = -8367567842003252055L;
      private String name ; 
      public void setName(String name) {  
          this.name = name;  
     }
     public String getName() {
         return name;
     } 
     public ListenerTest(String name) {
         this.name = name;
     }
   //对象实例化后保存到session中,当session失效要被序列化前执行,(只有保存到session中的对象才会被监听到)
     public void sessionWillPassivate(HttpSessionEvent se) {
         System.out.println(name + "=>序列化到(钝化)到硬盘中,JSessionId是:"+se.getSession().getId()); 
    }
   //当session被反序列化后执行
     public void sessionDidActivate(HttpSessionEvent se) {
         System.out.println(name + "=>反序列化到(活化)到内存中,JSessionId是:"+se.getSession().getId());
     }

jsp页面

<%  
	session.setAttribute("sessionBean",new ListenerTest("AAAA"));
%>

需要注意的是存在该session时候在序列化有可能导致失败 稍等一会就好了

User 实体类

	public class User {  
	    //当前用户的session id  
	    private String sessionId;  
	    //当前用户的ip地址  
	    private String ip;  
	    //当前用户第一次访问的时间  
	    private String firstTime;  
	    public User() {  
	        super();  
	          
	    }  
	    public String getIp() {  
	        return ip;  
	    }  
	    public void setIp(String ip) {  
	        this.ip = ip;  
	    }  
	    public String getFirstTime() {  
	        return firstTime;  
	    }  
	    public void setFirstTime(String firstTime) {  
	        this.firstTime = firstTime;  
	    }  
	    public String getSessionId() {  
	        return sessionId;  
	    }  
    public void setSessionId(String sessionId) {  
	        this.sessionId = sessionId;  
	    }  	      
	}  

HttpSessionListener监听器

	@WebListener  
	public class MyHttpSessionListener implements HttpSessionListener{  
	    //当前用户数  
	    private int userCounts=0;  
	    @Override  
	    public void sessionCreated(HttpSessionEvent se) {  
	        //sessionCreated  用户数+1  
	        userCounts++;  
	        //重新在servletContext中保存userCounts  
	        se.getSession().getServletContext().setAttribute("userCounts", userCounts);  
	          
	    }  
	    @Override  
	    public void sessionDestroyed(HttpSessionEvent se) {  
	        //sessionDestroyed  用户数-1  
	        userCounts--;  
	        //重新在servletContext中保存userCounts  
	        se.getSession().getServletContext().setAttribute("userCounts", userCounts);  
	          
	        @SuppressWarnings("unchecked")  
	        ArrayList<User> userList=(ArrayList<User>) se.getSession().getServletContext().getAttribute("userList");  
	        String sessionId=se.getSession().getId();  
	        //如果当前用户在userList中  在session销毁时  将当前用户移出userList  
	        if(SessionUtil.getUserBySessionId(userList, sessionId)!=null){  
	            userList.remove(SessionUtil.getUserBySessionId(userList, sessionId));  
	        }  
	        //将userList集合  重新保存到servletContext  
	        se.getSession().getServletContext().setAttribute("userList", userList);  
	    }  
	  
	}  

ServletRequestListener监听器

	@WebListener  
	public class MyServletRequestListener implements ServletRequestListener {  
	    //用户集合  
	    private ArrayList<User> userList;  
	    @Override  
	    public void requestDestroyed(ServletRequestEvent arg0) {  	              
	    }  
	  
	    @SuppressWarnings("unchecked")  
	    @Override  
	    public void requestInitialized(ServletRequestEvent arg0) {  
	        //从servletContext中获的userList  
	        userList=(ArrayList<User>) arg0.getServletContext().getAttribute("userList");  
	        //如果servletContext中没有userList对象  初始化userList  
	        if(userList==null){  
	            userList=new ArrayList<User>();  
	        }  
	        HttpServletRequest request=(HttpServletRequest) arg0.getServletRequest();  	          
	        //sessionId  
	        String sessionId=request.getSession().getId();  
	        //如果当前sessionId不存在集合中  创建当前user对象  
	        if(SessionUtil.getUserBySessionId(userList,sessionId)==null){  
	            User user=new User();  
	            user.setSessionId(sessionId);  
	            user.setIp(request.getRemoteAddr());  
	            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:MM:ss");  
	            user.setFirstTime(sdf.format(new Date()));  
	            userList.add(user);  
	        }  
	        //将userList集合 保存到ServletContext  
	        arg0.getServletContext().setAttribute("userList", userList);  
	    }  
	}  

工具类

	public class SessionUtil {  
	    //根据sessionId判断当前用户是否存在在集合中  如果存在 返回当前用户  否则返回null  
	    public static User getUserBySessionId(ArrayList<User> userList,String sessionId) {  
	        for (User user : userList) {  
	            if(sessionId.equals(user.getSessionId())){  
	                return user;  
	            }  
	        }  
	        return null;  
	    }  
	}  

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security是一个强大的身份验证和授权框架,用于保护Spring应用程序的安全性。下面是Spring Security的基础用法和一些常见知识点的详解: 1. 配置Spring Security:在Spring项目中,需要添加Spring Security的依赖,并配置相应的安全配置类(继承自 `WebSecurityConfigurerAdapter`),通过重写方法来配置身份验证和授权规则。 2. 身份验证(Authentication):Spring Security提供了多种身份验证方式,包括基于表单、HTTP基本认证、OAuth等。可以通过配置认证提供者(Authentication Provider)来定义如何验证用户的身份。 3. 授权(Authorization):通过配置访问控制规则,可以限制用户对特定资源的访问权限。Spring Security提供了多种授权方式,如基于角色、权限、表达式等。 4. 用户和角色管理:Spring Security可以与数据库或其他存储系统集成,用于管理用户信息和角色。可以自定义用户详细信息服务(UserDetailsService)和密码编码器(PasswordEncoder)来获取用户信息和验证密码。 5. 登录和注销:通过配置登录页面和注销功能,用户可以进行登录和退出操作。Spring Security提供了默认的登录页面和注销处理,也可以自定义实现。 6. CSRF防护:Spring Security默认开启CSRF(跨站请求伪造)防护功能,可以防止恶意网站利用用户的身份发起跨站请求。可以通过配置全局或特定URL的CSRF保护。 7. Remember-Me功能:Spring Security提供了Remember-Me功能,允许用户在下次访问时自动登录。可以通过配置持久化令牌的方式实现。 8. 安全事件和日志:Spring Security可以记录安全相关的事件和日志,包括认证成功、失败、访问被拒绝等。可以通过自定义的 `ApplicationListener` 或配置日志记录器来处理和记录这些事件。 9. 自定义过滤器和拦截器:通过自定义过滤器或拦截器,可以在请求处理过程中添加额外的安全逻辑。Spring Security提供了多个预定义的过滤器和拦截器,也可以自定义实现。 10. 方法级安全性:Spring Security支持方法级别的安全性控制,可以通过注解(如 `@Secured`、`@PreAuthorize`)或表达式(如 `hasRole()`、`hasPermission()`)来限制方法的访问权限。 11. 扩展和定制:Spring Security提供了丰富的扩展点,可以根据需求进行定制开发。例如,自定义认证提供者、用户详细信息服务、访问决策管理器等。 这些是Spring Security的基础用法和常见知识点的概述。具体使用时,可以根据项目需求和实际情况进行配置和定制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值