过滤器 Filter:

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或 servlet 处理

通常都是用来拦截 request 进行处理的,也可以对返回的 response 进行拦截处理。

过滤器的入门使用:

  • 创建一个类实现 filter 接口
  • 重写方法,在doFilter()方法中写拦截的具体内容
  • 根据情况决定是否放行
  • 配置 Filter 的拦截路径(web.xml)
  • 1.以指定资源匹配:" /index.jsp "
  • 2.以目录匹配:" /servlet/* "
  • 3.以后缀名匹配:" *.do "
  • 4.统配符,拦截所有web资源:" /* "

注意:过滤器是在服务器启动时就会创建的,只会创建一个实例,常驻内存,也就是说服务器一启动就会执行 filter 的 init()方法,当 filter 被移除或服务器正常关闭时,会执行destroy()方法。

生命周期:

  • 服务器启动,filter 创建,只创建一次
  • 随机立即初始化,只初始化一次
  • 灭磁拦截到都会执行 doFilter 方法
  • 服务器宕机销毁

拦截器链:

  • 项目中可以设置多个拦截器
  • 创建类实现接口,重写方法
  • 根据情况放行,放行到下一个拦截
  • 多个拦截器的执行顺序,按照web.xml上下顺序执行
  • 执行顺序跟<filter>的顺序无关<filter-mapping>的顺序才决定执行顺序
  • 如果是注释配置,那么就按照类名首字母顺序执行

过滤器链执行的特点:

  • 所有的Filter 和目标资源默认都执行同一个线程
  • 多个Filter 过滤器同时执行的时候,它们都要使用同一个Request 对象

全局编码格式过滤:

防止中文乱码,使用拦截器对所有请求拦截,设置编码,然后放行

//编码过滤器
public class EncodingFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException{ }

    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        // 1.将request,response强制转换成Http协议下使用request,与response
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // 2.操作--将编码问题解决
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        // 1.得到一个request装饰后的对象.
        HttpServletRequest myreq=new MyRequest(request);
        // 3.放行
        chain.doFilter(myreq, response);
    }

    public void destroy() {  }
}


身份认证拦截器:

使用拦截器,将身份过滤的代码前置到拦截器,对每个请求先进行身份认证

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter("/*")
// @WebFilter("/hw/*")
// @WebFilter("*.do")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    /**
     * 对请求的身份进行认证
     * 请求中获得session,且session中有登录时存入的数据,说明登录成功,放行
     * 请求中获得session,但是session中没有数据,说明没有登录,重定向到登录页
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        // 获取session
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession( );

        String requestURI = req.getRequestURI( );

        /**
         * 因为是拦截所有 /*
         * 所以要放行 静态资源以及第一次登录的请求
         */
        if(requestURI.contains("/login") ||requestURI.contains("html") || requestURI.contains("js") || requestURI.contains("css")) {
            // 放行
            chain.doFilter(request, response);
            return;
        }

        // 从session获得数据
        String username = (String) session.getAttribute("username");

        // 判断
        if (username != null){
            // 放行
            chain.doFilter(request, response);
        } else {
            HttpServletResponse resp = (HttpServletResponse) response;
            resp.sendRedirect(req.getContextPath()+"/index.html");
        }

    }

    @Override
    public void destroy() { }
}