day12_Filter_Listener
Filter
1. Filter【过滤器】简介
1.1 生活中过滤器
- 空气净化器
- 净水器
- 口罩等
1.2 程序中过滤器【Filter】
- Servlet:处理请求,做出响应
- Filter:过滤请求&响应【之前】
- 如:处理请求之前,解决字符集问题,交给过滤器处理
2. Filter使用
Filter服务器端三大组件之一【Servlet\Listener】
服务器端组件共性
1. 都需要实现某个接口
2. 都需要注册【web.xml&注解】
2.1 Filter常用API
- Filter接口:javax.servlet.Filter
- init(FilterConfig config):初始化方法
- doFilter(ServletRequest req,ServletResponse res,FilterChain chain)
- 过滤请求&响应
- destroy():销毁方法
- FilterConfig:封装Filter配置信息,每个Filter对应唯一一个FilterConfig对象。
- getFilterName():获取Filter名称
- getServletContext():获取servlet上下文对象
- getInitParameter():获取初始化参数
- FilterChain:封装Filter链信息
- doFilter():方法用于调用Filter链上的下一个过滤器,如果当前过滤器为最后一个过滤器则将请求发送到目标资源。【放行请求】
2.2 Filter之Helloworld
/*
@author Chunsheng Zhang 尚硅谷
@create 2021/8/18 14:28
/
public class Filter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override<br /> public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {<br /> System.out.println("Filter1->放行前,过滤请求!");<br /> // 省略10000代码<br /> //放行请求<br /> chain.doFilter(request,response);<br /> //放行后<br /> System.out.println("Filter1->放行后,过滤响应!");<br /> }
@Override<br /> public void destroy() {
}<br />}<br /><filter><br /> <filter-name>Filter1</filter-name><br /> <filter-class>com.atguigu.filter.Filter1</filter-class><br /> </filter><br /> <filter-mapping><br /> <filter-name>Filter1</filter-name><br /><!-- 对于过滤器,url一般不会设置/FilterName--><br /> <url-pattern>/TestFilterServlet</url-pattern><br /> </filter-mapping><br />
3. Filter工作原理【单个Filter】
- 请求被Filter过滤URL
- 执行Filter中doFilter()方法的放行前代码,过滤请求
- 执行chain.doFilter(request,response);放行请求,执行目标资源【Servlet】,处理请求,做出响应
- 执行Filter中doFilter()方法的放行后代码,过滤响应
- 响应
4. Filter生命周期
- 构造器
- 执行时机:启动服务器时,创建Filter
- 执行次数:在整个生命周期中,只执行一次【单例】
- init()
- 执行时机:启动服务器时,执行构造器之后,执行
- 执行次数:在整个生命周期中,只执行一次
- doFilter()
- 执行时机:每次触发指定URL时,执行doFilter()【过滤请求,过滤响应】
- 执行次数:在整个生命周期中,执行多次
- destroy()
- 执行时机:关闭服务器时,执行
- 执行次数:在整个生命周期中,执行一次
5. Filter工作原理【多个Filter】
- 请求被Filter过滤URL
- 执行Filter1中doFilter()方法的放行前代码,过滤请求,执行chain.doFilter(request,response);放行请求
- 执行Filter2中doFilter()方法的放行前代码,过滤请求,执行chain.doFilter(request,response);放行请求
- 执行目标资源【Servlet】,处理请求,做出响应
- 执行Filter2中doFilter()方法的放行后代码,过滤响应
- 执行Filter1中doFilter()方法的放行后代码,过滤响应
- 响应
- Filter执行顺序由:
- web.xml注册中的filter-mapping顺序决定
- 注解中filter-name名称字母顺序决定,如:aFilter>bFilter
6. Filter中URL匹配规则
- 精确匹配
- url匹配
Filter1
com.atguigu.filter.Filter1
Filter1
/TestFilterServlet
- 名称匹配
Filter2
com.atguigu.filter.Filter2
Filter2
TestFilterServlet
- 模糊匹配【带有(*)号匹配】
- 后缀名匹配:【】书写在URL*最前面
- 如:
*.html
- 如:
- 目录匹配:【】书写在URL*最后面
- 如:
/pages/*
- 如:
- 注意:【*】不能书写在URL的中间位置
- 后缀名匹配:【】书写在URL*最前面
7. 最终版Filter【HttpFilter】
7.1 为什么需要HttpFilter
- 对比Servlet中,javax.servlet.Servlet接口与javax.servlet.http.HttpServlet类,使用HttpServlet优势如下:
- 提供获取对象方法【getServletConfig()和getServletContext】
- 将service()方法,抽象化【在子类中只关注service()】
- 重写service():类型转换
- 重载service():通过请求方式不同,调用不同处理方法
7.2 手动搭建HttpFilter思路
- 提供获取对象方法【getFilterConfig()和getServletContext】
- 将doFilter()方法,抽象化【在子类中只关注doFilter()】
- 重载doFilter()方法,类型转换
- 注意:HttpFilter是抽象类,不能实例化,所以不能注册
7.3 手动搭建HttpFilter示例代码
/*
@author Chunsheng Zhang 尚硅谷
@create 2021/8/18 16:19
/
public abstract class HttpFilter implements Filter {
private FilterConfig filterConfig;
/**<br /> * 获取FilterConfig对象方法<br /> * @return<br /> */<br /> public FilterConfig getFilterConfig() {<br /> return filterConfig;<br /> }
/**<br /> * 获取ServletContext对象方法<br /> * @throws ServletException<br /> */<br /> public ServletContext getServletContext(){<br /> return getFilterConfig().getServletContext();<br /> }
@Override<br /> public void init(FilterConfig filterConfig) throws ServletException {<br /> this.filterConfig = filterConfig;<br /> }
@Override<br /> public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {<br /> HttpServletRequest req = (HttpServletRequest)request;<br /> HttpServletResponse res = (HttpServletResponse)response;<br /> doFilter(req,res,chain);<br /> }
public abstract void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException;
@Override<br /> public void destroy() {
}<br />}<br />
8. 基于注解方式注册Filter
/*
@author Chunsheng Zhang 尚硅谷
@create 2021/8/18 15:42
/
@WebFilter(filterName = “Filter3”,value = “*.html”)
public class Filter3 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {<br /> System.out.println("Filter3.....");<br /> chain.doFilter(req, resp);<br /> }
public void init(FilterConfig config) throws ServletException {
}<br />}<br />