什么是监听器?
监听器
就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
Servlet监听器
在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession 和 ServletRequest 这三个域对象
。
Servlet监听器分为三大类
1、数据域对象创建和销毁监听器
2、数据域对象和属性变更监听器
3、绑定到 HttpSession 域中的某个对象的状态的事件监听器
ServletContextListener
ServletContextListener
: 用来监听ServletContext对象的创建和销毁。ServletContext对象代表全局唯一对象,每个web工程会产生一个ServletContext,服务器启动创建,服务器关闭销毁。其有两个方法contextInitialized
,contextDestroyed
分别在服务器启动时和关闭时调用。
public interface ServletContextListener extends EventListener {
default void contextInitialized(ServletContextEvent sce) {
}
default void contextDestroyed(ServletContextEvent sce) {
}
}
实战
@WebListener
public class MyContextListener implements ServletContextListener {
private static Logger logger = LoggerFactory.getLogger(MyContextListener.class);
@Override
public void contextDestroyed(ServletContextEvent arg0) {
logger.info("-------服务器停止-------");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
logger.info("-------服务器启动-------");
}
}
主流用法
ServletContextListener主流应用:
第一个:在服务器启动时,对一些对象进行初始化
,并且将对象保存ServletContext数据范围内(因为在监听器内可以获得事件源对象) — 全局数据
例如:创建数据库连接池
第二个:对框架进行初始化
例如:Spring框架初始化通过ServletContextListener (因为监听器代码在服务器启动时执行)
Spring框架(配置文件随服务器启动加载) org.springframework.web.context.ContextLoaderListener
第三个:实现任务调度,启动定时程序 (Timer、TimerTask) 使一个程序,定时执行。
HttpSessionListener
HttpSessionListener 用于监听session的创建和销毁
。
Session何时创建:request.getSession()
Session何时销毁:关闭服务器,Session过期,session.invalidate
*Session过期时间默认时间为30分钟,可以自己配置。
springboot 实战
@WebListener
public class MySessionListener implements HttpSessionListener {
private static Logger logger = LoggerFactory.getLogger(MySessionListener.class);
@Autowired
NewsService newsService;
@Override
public void sessionCreated(HttpSessionEvent arg0) {
// System.out.println("---------------开启Session监听器-------------------");
HttpSession session = arg0.getSession();
session.setMaxInactiveInterval(3 * 60);
ServletContext context = session.getServletContext();
ArrayList<String> sessionList = (ArrayList<String>) context.getAttribute("sessionList");
sessionList.add(session.getId());//将会话id加入context上下文
// System.out.println("获取对象: "+sessionList);
context.setAttribute("sessionList", sessionList);
Map<Integer, Integer> newsIdVisit = new HashMap<Integer, Integer>();
session.setAttribute("newsIdVisit", newsIdVisit);//每个会话的新闻访问情况
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
logger.info("---------------关闭Session监听器-------------------");
HttpSession session = arg0.getSession();
ServletContext context = session.getServletContext();
ArrayList<String> sessionList = (ArrayList<String>) context.getAttribute("sessionList");
if (sessionList.contains(session.getId())) {
sessionList.remove(session.getId());
}
System.out.println("销毁后的SessionId: " + session.getId());
context.setAttribute("sessionList", sessionList);
//获取该会话的新闻访问信息
Map<Integer, Integer> newsIdVisit = (Map<Integer, Integer>) session.getAttribute("newsIdVisit");
newsService.updateVisitNum(newsIdVisit);
logger.info("保存浏览次数完毕");
}
}
ServletRequestListener
ServletRequestListener:监听request对象创建,监听request对象销毁。
Request何时创建:请求发起时创建
Request何时销毁:响应结束时销毁
例如:每次刷新界面都会创建销毁一次
springBoot 实战
@WebListener
public class MyListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
HttpSession session = request.getSession();//创建或获取session
String url = request.getRequestURI();//获取访问新闻页面的url
if (url.equals("/newsDetail")) {//如果访问新闻详情页面
// System.out.println("---------------开启新闻页面监听器-------------------");
int newsId = Integer.parseInt(request.getParameter("newsId"));//获取新闻id
Map<Integer, Integer> newsIdVisit = (Map<Integer, Integer>) session.getAttribute("newsIdVisit");
if (!newsIdVisit.containsKey(newsId)) {//如果没有访问过该条新闻,则记录一次访问数
newsIdVisit.put(newsId, 1);
session.setAttribute("newsIdVisit", newsIdVisit);
}
}
}
}