是指专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生变化时,立即采取相应的行动。
web监听器由servlet规范提供的,它可以监听客户端的请求,服务端的操作,监听的对象包括ServletContext,HttpSession,ServletRequest三个预对象(内置对象),分别对应aplication,session,request。
JSP中一共预先定义了9个这样的内置对象,分别为:request、response、session、application、out、pagecontext、config、page、exception
内置对象(又叫隐含对象)特点:
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。
application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。
Servlet规范中定义的一种特殊类
用于监听ServletContext,HttpSession和ServletRequest等域对象的创建与销毁事件用于监听域对象的属性发生修改的事件可以在事件发生前,发生后做一些必要的处理
1.统计在线人数和在线用户
2.系统启动时加载初始化信息
3.统计网站访问量
4.跟Spring结合
package com.java.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @author : xiayj
* @date : 2019/8/3 17:58
*/
public class FirstListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed");
}
}
把监听对象放到web.xml中
com.java.listener.FirstListener
index.jsp
BASIC
启动tomcat,控制台输出如下说明当web应用启动时会自动创建一个application对象,且只有一个
关闭tomcat,如下表示当前应用销毁
1)用于监听应用程序环境对象(ServletContext)的事件监听器
2)用于监听用户会话对象(HttpSession)的事件监听器
3)用于监听请求消息对象(ServletRequest)的事件监听器
ServletContext实现了ServletContextListener用于监听它的创建与销毁事件,一个web项目可以定义多个ServletContextListener,但一个web项目只有一个ServletContext对象。
ServletContextListener有两个事件处理方法,这两个方法都会传入ServletContextEvent事件对象,可以获取ServletContext对象以及一些初始化参数。ServletContextListener主要用途:可以做定时器,加载全局属性对象,创建全局的数据库连接,加载一些缓存信息。
web.xml配置如下
com.java.listener.FirstListener
index.jsp
BASIC
initParam
listener
代码实现:
package com.java.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @author : xiayj
* @date : 2019/8/3 17:58
*/
public class FirstListener implements ServletContextListener {
//ServletContext是上下文对象,当web应用启动时创建,web应用销毁时销毁
@Override
public void contextInitialized(ServletContextEvent sce) {
//项目启动时获取初始化参数
String initParam = sce.getServletContext().getInitParameter("initParam");
System.out.println("contextInitialized : initParam = " + initParam);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//销毁主要用于当数据库连接关闭时释放一些不必要的资源
System.out.println("contextDestroyed");
}
}
项目启动结果如下,说明当项目启动时就加载了在web.xml中配置的参数
与ServletContext类似,HttpSession实现了HttpSessionListener用于监听它的创建与销毁事件,一个web项目可以定义多个HttpSessionListener,但一个web项目只有一个HttpSession对象。HttpSessionEvent事件对象,可以获取当前被创建的HttpSession对象。HttpSessionListener主要用途:统计在线人数,记录访问日志。
Session创建:用户打开浏览器第一次访问我们应用时,这次会话web容器会分配一个session,可以在session中保存一些信息
Session销毁:1.手动点退出,关闭服务器2.关闭浏览器一段时间直到session过期3.不关闭浏览器,session超时
实现HttpSessionListener:
package com.java.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* @author : xiayj
* @date : 2019/8/4 16:59
*/
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("sessionCreated");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("sessionDestroyed");
}
}
web.xml文件加如下配置
1
访问项目
控制台输出如下Listener监听到session创建
等一分钟后,监听到session被销毁
ServletRequest实现了ServletRequestListener用于监听它的创建与销毁事件,一个web项目可以定义多个ServletRequestListener,但一个web项目只有一个ServletRequest对象。ServletRequestListener主要用途:读取request里的参数,记录访问历史,路径。
实现ServletRequestListener
package com.java.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
/**
* @author : xiayj
* @date : 2019/8/4 17:54
*/
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
//获取当前的请求参数
String name = sre.getServletRequest().getParameter("name");
System.out.println("requestInitialized");
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("requestDestroyed");
}
}
Web.xml中增加监听器配置信息
com.java.listener.MyServletRequestListener
启动项目,打开浏览器,查看控制台如下,可知request监听到了用户的访问请求,并在请求结束后销毁
package com.java.listener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
/**
* @author : xiayj
* @date : 2019/8/10 17:18
*/
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
//可知是什么对象添加了什么属性,移除了什么属性 System.out.println("ServletRequest_attributeAdded:"+srae.getName());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest_attributeRemoved:"+srae.getName());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest_attributeReplaced:"+srae.getName());
}
}
package com.java.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
* @author : xiayj
* @date : 2019/8/10 16:55
*/
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("HttpSession_attributeAdded:"+se.getName());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("HttpSession_attributeRemoved:"+se.getName());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("HttpSession_attributeReplaced:"+se.getName());
}
}
package com.java.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
/**
* @author : xiayj
* @date : 2019/8/10 16:52
*/
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("ServletContext_attributeAdded:"+scae.getName());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("ServletContext_attributeRemoved:"+scae.getName());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("ServletContext_attributeReplaced:"+scae.getName());
}
}
Web.xml文件中注册监听器
com.java.listener.MyHttpSessionAttributeListener
com.java.listener.MyServletContextAttributeListener
com.java.listener.MyServletRequestAttributeListener
创建新增各个属性值得jsp界面,为了方便在每个页面都加上了初始化,销毁的按钮
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
这是myweb应用
你好!这是一个listener
init.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServletPath();
//添加属性,让Listener监听执行attributeAdded方法
request.setAttribute("requestName","requestValue");
request.getSession().setAttribute("sessionName","sessionValue");
request.getSession().getServletContext().setAttribute("contextName","contextValue");
%>
Title
这是初始化值得界面
destory.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServletPath();
//移除属性,让Listener监听执行attributeRemoved方法
request.removeAttribute("requestName");
request.getSession().removeAttribute("sessionName");
request.getSession().getServletContext().removeAttribute("contextName");
%>
Title
这是销毁界面
超时时间改为0
0
打开主页面
点击init,控制台输出如下
再次点击init
点击destory,属性被移除,request对象因为已经被销毁了,域中已没有requestName属性,所以没有移除信息
绑定:通过getSession().setAttribute将对象保存到session对象中
解除绑定:通过getSession().removeAttribute将对象从session对象中移除
钝化:将session对象持久化到存储设备上
活化:将session对象从存储设备上恢复
package com.java.entity;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;
/**
* @author : xiayj
* @date : 2019/8/17 16:09
*/
/** 想要钝化或活化必须实现Serializable接口*/
public class User implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable {
private String username;
private String password;
/** 对象绑定执行*/
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("valueBound Name:"+event.getName());
}
/** 对象解除绑定执行*/
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("valueUnbound Name:"+event.getName());
}
/** 钝化*/
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("sessionWillPassivate"+se.getSource());
}
/** 活化*/
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("sessionDidActivate"+se.getSource());
}
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;
}
}
在init文件里增加如下:
//将用户实例放到session中
request.getSession().setAttribute("currentUser",new com.java.entity.User());
在destory文件里增加如下:
request.getSession().removeAttribute("currentUser");
启动项目,打开首页:
点击init和destory,控制台分别输出如下,表明当对象实现HttpSessionBindingListener接口后,只要对象被session绑定,就会触发事件,执行valueBound方法,当解除绑定后,执行valueUnBound方法
启动tomcat,打开项目,可以看到控制台已经创建session
点击init,可以看到session中保存了几个属性值
关闭tomcat,控制输出如下,sessionWillPassivateorg.apache.catalina.session.StandardSessionFacade@1e7c7811 就是session钝化的输出,StandardSession是默认的钝化管理器
钝化的文件保存位置如下
在首页新增如下:
<%=request.getSession().getAttribute("currentUser")%>
你好!这是一个listener
重启tomcat,控制台输出如下:
打开首页,可以看到之前钝化的user对象被输出
Ps:如果出现可以活化,但是无法钝化的问题即重启tomcat没有调用 sessionDidActivate()方法,浏览器端也获取不到重启前存入的对象
这是因为每次重启tomcat会将如下目录删除并重新生成,之前钝化的session文件也会被一起删除
解决方法:在tomcat安装目录下conf/context.xml配置文件里增加如下配置,directory里是自定义的session文件存储路径
在Servlet3.0版本以上提供@WebListener注解将一个实现了特定监听器接口(比如ServletContextListener,HttpSessionListener)的类定义为监听器,这样在web应用中使用监听器时不需要在web.xml文件中配置监听器的相关描述信息,感兴趣的可以自己去研究一下,用法差不多。
参考文章:Jsp:九大内置对象https://my.oschina.net/u/3805464/blog/1813805
本文章内容是对慕课网课程内容的一个总结,感兴趣的同学可以去慕课网学习该课程
地址如下:https://www.imooc.com/learn/271