Java Web Filter 过滤器

基本概念

  • Filter 过滤器它是 JavaEE 的规范,也就是接口
  • Filter 过滤器它的作用是:拦截请求,过滤响应
  • 拦截请求常见的应用场景有: 1、权限检查 2、日记操作 3、事务管理 等等

应用

  • 有一个 admin 目录。这个 admin 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必须是用户登录之后才允许访问
    在这里插入图片描述
  • 过滤所有在admin文件夹内的文件
    public class AdminFilter implements Filter {
      public void init(FilterConfig config) throws ServletException {
      }
    
      public void destroy() {
      }
    
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpSession session = httpServletRequest.getSession();
        // 判断是否有已经登录的记录
        Object user = session.getAttribute("user");
        if (user == null) {
          request.getRequestDispatcher("/login.jsp").forward(request, response);
          return;
        }
        chain.doFilter(request, response);
      }
    }
    
    <filter>
        <filter-name>AdminFilter</filter-name>
        <filter-class>com.du.javaweb.filter.AdminFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AdminFilter</filter-name>
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
    
  • admin文件夹内的文件
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>管理员界面</title>
    </head>
    <body>
    这是管理员界面
    </body>
    </html>
    
  • 登录界面及Servlet
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录界面</title>
        <base href="http://localhost:8080/filter/">
    </head>
    <body>
    <form action="LoginServlet" method="post">
        <label for="name"> 登录名 </label><input type="text" name="name" id="name"><br/>
        <label for="password"> 密码 </label><input type="password" name="password" id="password"><br/>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>
    
    @WebServlet(name = "LoginServlet", value = "/LoginServlet")
    public class LoginServlet extends HttpServlet {
      @Override
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        String name = request.getParameter("name");
        String password = request.getParameter("password");
    
        if ("jack".equals(name) && "123".equals(password)) {
          response.getWriter().write("登录成功");
          request.getSession().setAttribute("user", true);  // 在session中保存登录成功记录,只要是非空就好
          return;
        }
        RequestDispatcher dispatcher = request.getRequestDispatcher("/login.jsp");
        dispatcher.forward(request, response);
      }
    
      @Override
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
      }
    }
    

Filter 的生命周期

  • Filter 的生命周期包含几个方法
    1. 构造器方法
    2. init 初始化方法。
    3. doFilter 过滤方法 第 3 步,每次拦截到请求,就会执行
    4. destroy 销毁 第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)

    第 1、2 步,在 web 工程启动的时候执行(Filter 已经创建)

FilterConfig 类

  • FilterConfig 类,它是 Filter 过滤器的配置文件类。
  • Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息
    public void init(FilterConfig config) throws ServletException {
        System.out.println("这是AdminFilter的init()方法");
        // 获取过滤器的名字
        String filterName = config.getFilterName();
        System.out.println(filterName);
        // 获取servletContext对象
        ServletContext servletContext = config.getServletContext();
        System.out.println(servletContext);
        System.out.println(servletContext.getInitParameter("context_param"));
        // 获取初始化参数的值
        String param = config.getInitParameter("param");
        System.out.println(param);
        // 获取所有初始化参数的名字
        Enumeration<String> initParameterNames = config.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
          System.out.println(initParameterNames.nextElement());
        }
      }
    
    <filter>
        <filter-name>AdminFilter</filter-name>
        <filter-class>com.du.javaweb.filter.AdminFilter</filter-class>
        <init-param>
            <param-name>param</param-name>
            <param-value>value</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>AdminFilter</filter-name>
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
    

FilterChain 过滤器链

在这里插入图片描述

@WebFilter(filterName = "Filter1", urlPatterns = "/index.jsp")
public class Filter1 implements Filter {
  public void init(FilterConfig config) throws ServletException {
  }

  public void destroy() {
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    System.out.println("Filter1 开始");
    chain.doFilter(request, response);
    System.out.println("Filter1 结束");
  }
}
@WebFilter(filterName = "Filter2", urlPatterns = "/index.jsp")
public class Filter2 implements Filter {
  public void init(FilterConfig config) throws ServletException {
  }

  public void destroy() {
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    System.out.println("Filter2 开始");
    chain.doFilter(request, response);
    System.out.println("Filter2 结束");
  }
}
  • 就像一个栈一样,输出顺序是。两个Filter的先后顺序主要看在xml的声明顺序。(这个例子用注解声明,那就不知道怎么确定了。可能是ASCII码吧)
    Filter1 开始
    Filter2 开始
    Filter2 结束
    Filter1 结束
    

Filter 的拦截路径

  • 精确匹配
    <url-pattern>/target.jsp</url-pattern>
    
    以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/target.jsp
  • 目录匹配
    <url-pattern>/admin/*</url-pattern>
    
    以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/admin/*
  • 后缀名匹配
    <url-pattern>*.html</url-pattern>
    
    以上配置的路径,表示请求地址必须以.html 结尾才会拦截到
  • Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!所以,就算请求的网页不存在,只要URL在过滤器的“管辖范围”,就会对它进行管制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值