Listener(监听器)
> 监听某个事件的发生,其内部机制就是接口回调
一、接口回调
> 事先先把一个对象传递给 A , 当A 执行到5的时候,通过这个对象,来调用B中的方法。
二、Web监听器
<listener> <listener-class>实现监听器接口的类的全名称(xx.xxx.xxxx.MyServletContextListener)</listener-class> </listener>
### 总共有8个 划分成三种类型
Ⅰ、监听三个作用域创建和销毁
作用域有:
pageContext --- 当前页面
request --- httpServletRequest
session --- httpSession
application --- ServletContext
1、ServletContextListener(application作用域):用于监听ServletContext的创建和销毁
servletcontext创建: 启动服务器的时候
servletContext销毁:关闭服务器. 从服务器移除项目
2、ServletRequestListener(request作用域):用于监听Request的创建和销毁
request创建:访问服务器上的任意资源都会有请求出现。
访问 html: 会
访问 jsp: 会
访问 servlet : 会
request销毁:服务器已经对这次请求作出了响应。
3、HttpSessionListener(Session作用域):用于监听Request的创建和销毁
session的创建:只要调用getSession
html:不会
jsp:会 默认调用getSession();
servlet::会(必须在代码中调用getSession())
session的销毁:超时(一般情况30分钟)、服务器非正常关闭
作用:
ServletContextListener
1. 完成自己想要的初始化工作
2. 执行自定义任务调度。 执行某一个任务。
HttpSessionListener
统计在线人数
Ⅱ、 监听三个作用域属性状态变更
### 可以监听在作用域中值 添加 | 替换 | 移除的动作。
1、servletContext --- ServletContextAttributeListener
2、request --- ServletRequestAttributeListener
3、session --- HttpSessionAttributeListener
session.setAttribute("name","zhangsan");//attributeAdded方法监听
session.setAttribute("name","lisi");//attributeReplaced方法监听
session.removedAttribute("name");//attributeRemoved方法监听
Ⅲ、监听httpSession里面值的状态变更
这一类监听器不用注册
1、HttpSessionBindingListener:监听对象与session 绑定和解除绑定 的动作
让javaBean 实现该接口即可
@Override public void valueBound(HttpSessionBindingEvent event) { System.out.println("对象被绑定进来了"); } @Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("对象被解除绑定"); }
javaBean对象存放到session中
session.setAttribute(javaBean对象); session.removedAttribute(javaBean对象);
2、HttpSessionActivationListener:用于监听现在session的值 是 钝化 (序列化)还是活化 (反序列化)的动作
钝化 (序列化):把内存中的数据 存储到硬盘上
活化 (反序列化):把硬盘中的数据读取到内存中。
实例:
服务器正常关闭,会使Session钝化,服务器启动Session活化
①、JavaBean实现HttpSessionActivationListener和Serialzable(用于序列化和反序列化,不实现此接口就无法把硬盘数据读到存储中)
public class Bean02 implements HttpSessionActivationListener,Serialzable{ private String name; public String getName(){ return name; } public void setName(String name){ this.name = name; } @Override public void sessionWillPassivate(HttpSessionEvent se){ System.out.println("Session中的值(Bean02对象)被钝化了...") } @Override public void sessionDidActivate(HttpSessionEvent se){ System.out.println("Session中的值(Bean02对象)被活化了...") } }
②、session存储JavaBean对象
<% Bean02 bean = new Bean02(); bean.setName("xiaoxiao"); session.setAttribute("sessionkey_bean",bean); %>
③、获取session中的数据
<% sessionkey_bean.getName() %>
可以通过正常关闭服务器测试。
④、通过配置让session在一定时间内钝化
在tomcat里面 conf/context.xml 里面配置:对所有的运行在这个服务器的项目生效
在conf/Catalina/localhost/context.xml 配置:对 localhost生效(localhost:8080)
在自己的web工程项目中的 META-INF/context.xml:只对当前的工程生效
配置内容:
<Context> <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"> <Store className="org.apache.catalina.session.FileStore" directory="xxx"/> </Manager> </Context>
maxIdleSwap : 1分钟不用就钝化
directory : 钝化后的那个文件存放的目录位置。( omcatapache-tomcat-7.0.52workCatalinalocalhost项目名xxx(directory的值))
Filter(过滤器)
> 其实就是对客户端发出来的请求进行过滤。 浏览器发出, 然后服务器派servlet处理。 在中间就可以过滤, 其实过滤器起到的是拦截的作用
一、使用Filter
1、定义一个类, 实现Filter接口
public class FilterDemo implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("来到过虑器了。。。"); chain.doFilter(request, response); } public void init(FilterConfig fConfig) throws ServletException { } }
2、注册过滤器
<filter> <display-name>FilterDemo</display-name> <filter-name>FilterDemo</filter-name> <filter-class>com.itheima.filter.FilterDemo</filter-class> </filter> <filter-mapping> <filter-name>FilterDemo</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
二、Filter的生命周期
* 创建:服务器启动
* 销毁:服务器停止
三、Filter执行顺序
1、客户端发出请求,先经过过滤器, 如果过滤器放行,那么才能到servlet
2、如果有多个过滤器, 那么他们会按照注册的映射顺序(<filter-mapping>的顺序)。 只要有一个过滤器不放行,那么后面排队的过滤器以及咱们的servlet都不会收到请求
<filter> <display-name>FilterDemo</display-name> <filter-name>FilterDemo</filter-name> <filter-class>com.itheima.filter.FilterDemo</filter-class> </filter> <filter> <display-name>FilterDemo02</display-name> <filter-name>FilterDemo02</filter-name> <filter-class>com.itheima.filter.FilterDemo02</filter-class> </filter> <filter> <display-name>FilterDemo03</display-name> <filter-name>FilterDemo03</filter-name> <filter-class>com.itheima.filter.FilterDemo03</filter-class> </filter> <filter> <display-name>FilterDemo04</display-name> <filter-name>FilterDemo04</filter-name> <filter-class>com.itheima.filter.FilterDemo04</filter-class> </filter> <filter-mapping> <filter-name>FilterDemo04</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>FilterDemo02</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>FilterDemo03</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>FilterDemo</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1、chain.doFilter(request, response); 放行, 让请求到达下一个目标
2、<url-pattern>/*</url-pattern>
全路径匹配 以 / 开始( /LoginServlet 访问LoginServlet,执行过滤器)
以目录匹配 以 / 开始 以 * 结束 (/demo01/* 访问demo01文件夹下的文件,执行过滤器)
以后缀名匹配 以 * 开始 以后缀名结束(*.jsp *.html *.do 访问具体的文件类型,执行过滤器)
3、dispatcher 设置
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
REQUEST:只要是请求过来,都拦截,默认就是REQUEST
FORWARD:只要是转发都拦截
ERROR:页面出错发生跳转
INCLUDE:包含页面的时候就拦截