Filter&Listener
Filter
1 . Filter 简介 [过滤器]
1.1Filter概述
- 生活中过滤器 : 如 , 空气净化器 , 净水器等.
- Filter : web三大组件之一
- web组件共性
- 都需要实现某个接口
- 都需注册 [ web . xml | 注解 ]
- web组件共性
1.2Filter作用
- Servlet : 处理请求 , 做出相应
- Filter : 过滤请求和相应
1.3Filter常用API
-
Filter接口
- init() : 用于Filter初始化
- doFilter() : 作用和service() 方法作用类似 . 是过滤请求和相应的 .
- destroy() : 用于Filter对象的销毁 .
-
FilterChain接口
-
doFilter() 方法 , 用于调用filter链上的下一个过滤器 , 如果当前过滤器是最后一个过滤器时 , 则将请求发送到目标资源 .
[放行请求]
-
-
FilterConfig接口
- getFilterName() : 获取Filter名称
- getServletContext() : 获取ServletContext对象
- getInitParameter() : 获取Filter的初始化参数
- getInitParameterNames() : 获取Filter初始化参数的名称
2.Filter工作原理[单个]
- Servlet : 处理请求 , 做出相应向服务器发送请求【/EndServlet】
- 执行过滤器doFilter方法中的 [放行请求之前] 代码
- 执行 : chain.doFilter()方法 , 放行请求
- 执行EndServlet , 处理请求 , 做出响应
- 执行过滤器doFilter方法的 【放行请求之后】代码
- 响应
3. Filter生命周期
Filtert生命周期
1 构造器
执行时机 : 第一次接收请求时【启动服务器】, 执行
执行次数 : 在整个生命周期只执行一次
2 init ()
执行时机 : 初始化方法
执行次数 : 在第1 , 2 步 在web工程启动的时候执行 一次
3 doFilter() 方法
执行时机 : 每次拦截到都会执行
执行次数 : 在整个生命周期中 , 执行 n 次 [n >= 1]
4 destroy() 方法
执行时机 : 在web 工程停止的时候
执行次数 : 在整个生命周期只执行一次
4.Filter工作原理[多个]
Filter的顺序由 配置顺序决定
5.URL的配置规则
5.1精确匹配
<!-- 方式一 -->
<filter>
<filter-name>Filter2</filter-name>
<filter-class>com.atguigu.filter.Filter2</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/EndServlet</url-pattern>
</filter-mapping>
<!-- 方式二 -->
<filter>
<filter-name>Filter2</filter-name>
<filter-class>com.atguigu.filter.Filter2</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter2</filter-name>
<servlet-name>/EndServlet</servlet-name>
</filter-mapping>
<!-- 要求访问地址必须是 : http://ip:port/工程路径/EndServlet -->
5.2模糊匹配
-
前置模糊 [后缀名] 匹配
- 将[*] 放到最前面 , 如 : *.jsp
-
后置模糊 [目录] 匹配
- 将[*] 放到最后面 , 如 : / 目录/ 目录2 /*
-
注意 : 【*】不能书写在中间位置:错误示范【/pages/*.jsp】
-
总结 : Filter 只关心请求的地址是否匹配 , 不关心请求的资源是否存在 .
<!--案例 模糊匹配--> <filter> <filter-name>Filter5</filter-name> <filter-class>com.atguigu.filter.Filter5</filter-class> </filter> <filter-mapping> <filter-name>Filter5</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>
在Servlet中 【/与/*区别】
【/*】:当前项目下的所有路径
【/】:【除了jsp之外的】当前项目下的所有路径
<!-- 如果没有配置Tomcatxml配置文件中 *.jsp的精度比/高 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- The mappings for the JSP servlet --> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping>
6.HttpFilter [HttpServlet]
-
手动搭建HTTPFilter思路
-
提供两个对象的获取方法
- getFilterConfig()
- getServletContext()
-
doFilter() 方法 , 抽象化 , 【在子类中只关注【重写】doFilter()即可】
-
重载doFilter方法,类型转换【ServletRequest->HttpServletRequest】
注意:HttpFilter中有doFilter()抽象方法,所以HttpFilter是抽象类,固不能注册HttpFilte
-
-
手动搭建HttpFilter代码
public abstract class HttpFilter implements Filter { private FilterConfig filterConfig; @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public abstract void doFilter(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException; @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 进行类型转换 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; doFilter(request,response,filterChain); } // 提供getFilterConfig 方法 public FilterConfig getFilterConfig() { return filterConfig; } public ServletContext getServletContext() { return filterConfig.getServletContext(); } }
Listener
1.Listener简介【监听器】
-
程序中监听器
- 监听者:程序员创建
- 监听对象:HttpServletRequest、HttpSession、ServletContext等
- 监听事件:创建、属性变化、销毁等
- 监听结果:项目需求
public class ListenerDemo implements ServletContextListener { public ListenerDemo() { System.out.println("监听器 构造器"); } /** * 创建时 初始化 * @param servletContextEvent */ @Override public void contextInitialized(ServletContextEvent servletContextEvent) { System.out.println("application init ()"); } /** * 销毁时调用 * @param servletContextEvent */ @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { System.out.println("application contextDestroyed () 对象销毁了 "); } }
<listener> <listener-class>com.atguigu.linstener.ListenerDemo</listener-class> </listener>
2.Listener示例代码
- 总结: 服务器创建三大组件顺序
- Listener > Filter > Servlet