监听器Liistener学习
- 能做什么事?
监听某一个事件的发生。 状态的改变。
- 监听器的内部机制
其实就是接口回调.
接口回调
- 需求:
A在执行循环,当循环到5的时候, 通知B。
事先先把一个对象传递给 A , 当A 执行到5的时候,通过这个对象,来调用B中的方法。 但是注意,不是直接传递B的实例,而是传递一个接口的实例过去。
Web监听器
总共有8个 划分成三种类型
- 定义一个类,实现接口
- 注册 | 在项目的web.xml中配置监听器 <listener>
- request —HttpServletRequest
- session —HttpSession
- application — ServletContext
总共有8个如下表所示
作用 | 实现接口 | 方法 |
---|---|---|
监听请求(request)域创建和销毁 | ServletRequestListener | 创建方法(requestInitialized) 销毁方法(requestDestroyed) |
监听session域创建和销毁 | HttpSessionListener | 创建方法(sessionCreated) 销毁方法(sessionDestroyed) |
监听application域创建和销毁 | ServletContextListener | 创建方法(contextInitialized) 销毁方法(contextDestroyed) |
监听在请求(request)域域中属性添加、替换、移除的动作。 | ServletRequestAttributeListener | 添加方法(attributeAdded) 替换方法(attributeReplaced) 移除方法(attributeRemoved) |
监听在session域域中属性添加、替换、移除的动作。 | HttpSessionAttributeListener | 添加方法(attributeAdded) 替换方法(attributeReplaced) 移除方法(attributeRemoved) |
监听在application域域中属性添加、替换、移除的动作。 | ServletContextAttributeListener | 添加方法(attributeAdded) 替换方法(attributeReplaced) 移除方法(attributeRemoved) |
监听httpSession里面存值的状态变更 | HttpSessionBindingListener | 绑定bean对象到session域中 (valueBound) bean对象从session中解绑 (valueUnbound) |
用于监听现在session的值 是 钝化 (序列化)还是活化 (反序列化)的动作 | HttpSessionActivationListener | 在tomcat里面 conf/context.xml 里面配置(后面会详细讲,但这个不常用) |
监听三个作用域创建和销毁
ServletRequestListener
- 监听事件
request创建:
访问服务器上的任意资源都会有请求出现。
访问 html: 会
访问 jsp: 会
访问 servlet : 会
request销毁:
服务器已经对这次请求作出了响应。
- 代码展示
新建Java类,实现ServletRequestListener接口
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
/**
* 监听请求域创建和销毁
*
*/
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("请求(request)域销毁");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
// 通过回调的事件对象参数,可以拿到对应的作用域对象
HttpServletRequest req = (HttpServletRequest) sre.getServletRequest();
String uri = req.getRequestURI();
System.out.println("请求域创建了,请求地址: " + uri);
}
}
- 在web.xml中注册监听器
<listener>
<listener-class>com.lanou3g.demo.RequestListener</listener-class>
</listener>
在浏览器中访问一个test.html(如果没有在项目中创建一个html文件)
在浏览器中访问test.jsp(没有就创建一个test.jsp)
在浏览器中访问test这个Servlet这个servlet代码如下:
package com.lanou.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;
import javax.servlet.http.HttpSession;
@WebServlet("/test")
public class TestServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 6918540495341071721L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sname = req.getParameter("sname");
req.setAttribute("sname", sname);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
req.setAttribute("sname", sname+"_new");
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().println("sname: " + sname);
}
}
访问这个servlet
控制台信息
HttpSessionListener
- 监听事件
session的创建
只要调用getSession
html: 不会
jsp: 会 getSession();
servlet: 会
session的销毁
超时 30分钟
非正常关闭 销毁
正常关闭服务器(序列化)
- 应用场景
统计在线人数.
- 实现示例
- 新建Java类,实现HttpSessionListener接口
package com.lanou.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 监听session域创建和销毁
*
*
*/
@WebListener
//通过注解方式注册Listener,等同于在web.xml中配置<listener>
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
//HttpSession session = se.getSession();// 通过回调的事件对象参数,可以拿到对应的作用域对象
System.out.println("Session域创建了...");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("Session域销毁了");
}
}
ServletContextListener
-
监听事件
-
ServletContext创建:启动服务器的时候
-
ServletContext销毁:关闭服务器. 从服务器移除项目
-
-
应用场景
在servletcontext创建的时候,
- 完成自己想要的初始化工作
- 执行自定义任务调度。 执行某一个任务。 Timer
- 实现示例
新建Java类,实现ServletContextListener接口
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext初始化");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext销毁");
}
}
监听三个作用域属性状态变更
可以监听在作用域中值 添加 | 替换 | 移除的动作。
ServletRequestAttributeListener
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
/**
* 监听请求域中属性添加、删除、替换操作
*
*/
@WebListener // 注册监听器
public class MyRequestAttrListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
// event.getServletContext();
// event.getServletRequest(); // 获取监听的请求域对象
String key = event.getName(); // 获取被添加到请求域中的属性key
Object value = event.getValue(); // 获取被添加到请求域中的属性value
System.out.println(key+ " 被添加到请求域中了, 值是: " + value);
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
String key = event.getName(); // 获取被添加到请求域中的属性key
System.out.println(key+ " 被从请求域中移除了");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
String key = event.getName(); // 获取被添加到请求域中的属性key
Object value = event.getValue(); // 获取被添加到请求域中的属性value
System.out.println("请求域中的属性: " +key+" 被替换了, 值是: " + value);
}
}
HttpSessionAttributeListener
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
* 监听请求域中属性添加、删除、替换操作
*
*/
// @WebListener // 注册监听器(也可以使用web.xml中配置的方式)
public class MySessionAttrListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
event.getSession(); // 获取监听的请求域对象
String key = event.getName(); // 获取被添加到Session域中的属性key
Object value = event.getValue(); // 获取被添加到Session域中的属性value
System.out.println(key+ " 被添加到Session域中了, 值是: " + value);
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
String key = event.getName(); // 获取被添加到Session域中的属性key
System.out.println(key+ " 被从Session域中移除了");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
String key = event.getName(); // 获取被添加到Session域中的属性key
Object value = event.getValue(); // 获取被添加到Session域中的属性value
System.out.println("Session域中的属性: " +key+" 被替换了, 值是: " + value);
}
}
ServletContextAttributeListener
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
/**
* 监听application域属性添加、删除、替换操作
* @author John
*
*/
@WebListener
public class MyServletContextAttrListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
event.getServletContext(); // 获取本身监听的域对象
event.getName(); // 获取本次添加到application域中属性的key
event.getValue(); // 获取本次添加到application域中属性的value
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
}
}
HttpSessionBindingListener
package com.lanou.bean;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import com.lanou.utils.WebUtils;
/**
* 这种监听器只关注实现了该接口的指定类型(User)类型数据从session中添加、移除的操作
* 并且,这种类型的监听器不需要注册
* @author John
*
*/
public class User implements HttpSessionBindingListener {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("User类型添加到Session中了");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("User类型从Session中移除了");
}
}
最后一个一般不常用所以就不写了,监听器基本入门,剩下的多做练习。