监听器监听三大域,ServletRequest,HttpSession, ServletContext三大域,可以分别监听三大域的生命周期事件和属性事件,监听什么,就实现什么接口,覆写相关方法。当监听的事件发生改变时,会执行覆写的方法。
如:想要监听ServletContext域的属性添加事件和生命周期出生事件,编写MyServletContextListener类
<listener>
<listener-class>cn.itcast.listener.MyServletContextListenerlistener-class>
listener>
由事件对象获得监听域对象
ServletContext servletContext = event.getServletConext();
由属性事件对象获得当前监听的域对象
1.HttpSession监听 :如JavaBean实现HttpSessionBindingListener接口,覆写以下两个方法,则可以监听javabean对象在session中的状态:
public void valueBound(HttpSessionBindingEvent event) 把监听器对象添加session中会调用监听器对象的本方法;
public void valueUnbound(HttpSessionBindingEvent event)方法,当把监听器对象移除到session中会调用监听器对象的本方法;
2.钝化 - HttpSessionActivationListener
Tomcat会在session从时间不被使用时钝化session对象,session中存储的对象也被纯化,当session被活化时,也会把session中存储的对象活化。
如果某个类实现了HttpSessionActiveationListener接口后,且实现Serializable接口当对象随着session被钝化和活化时,下面两个方法就会被调用:
public void sessionWillPassivate(HttpSessionEvent se):当对象感知被活化时调用本方法;
public void sessionDidActivate(HttpSessionEvent se):当对象感知被钝化时调用本方法;
过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。
当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”(在doFilter()方法中添加chain.doFilter(request, response)),那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。
其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。
Filter的三个方法:
l void init(FilterConfig):在Tomcat启动时被调用;
l void destroy():在Tomcat关闭时被调用;
l void doFilter(ServletRequest,ServletResponse,FilterChain):每次有请求时都调用该方法;
不放行:
public class HelloFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
System.out.println("Hello Filter");
}
public void destroy() {}
}
放行:
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
System.out.println("filter start...");
chain.doFilter(request, response);
System.out.println("filter end...");
}
<filter>
<filter-name>helloFilterfilter-name>
<filter-class>cn.itcast.filter.HelloFilterfilter-class>
filter>
<filter-mapping>
<filter-name>helloFilterfilter-name>
<url-pattern>/index.jspurl-pattern>
filter-mapping>
ServletContext getServletContext():获取ServletContext的方法;
void doFilter(ServletRequest,ServletResponse):放行!表示执行下一个过滤器,或者执行目标资源。可以在调用FilterChain的doFilter()方法的前后添加语句,在FilterChain的doFilter()方法之前的语句会在目标资源执行之前执行,在FilterChain的doFilter()方法之后的语句会在目标资源执行之后执行。
如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,如果不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。
.
执行顺序
一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序。
l REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
l FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、jsp:forward标签都是转发访问;
l INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、jsp:include标签都是包含访问;
l ERROR:当目标资源在web.xml中配置为中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。
如:
<filter-mapping>
<filter-name>myfilterfilter-name>
<url-pattern>/b.jspurl-pattern>
<dispatcher>REQUESTdispatcher>
<dispatcher>FORWARDdispatcher>
filter-mapping>
执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;
通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;