Back End

Filter和Listener

PineappleCat · 4月25日 · 2021年 107次已读

1.过滤器Filter

客户端与服务器的请求与响应进行过滤,拦截或修改。

例如:实现权限访问控制,过滤敏感词汇,压缩响应信息功能。

Servlet API提供了Filter接口,实现该接口,称为过滤器。

步骤如下:

  • 编写Java类实现Filter接口
  • 在doFilter核心方法中编写拦截逻辑
  • 设置拦截路径

手写过滤器

public class FirstFilter implements Filter {

  //init :初始化方法
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("FirstFilter的init方法..." + this.hashCode());
  }

  //doFilter: 执行过滤,核心方法
  //        request:请求对象
  //        response:响应对象
  //        chain:过滤器链
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    System.out.println("FirstFilter的doFilter方法...放行之前" + this.hashCode());
    //放行(如果有下一个过滤器,则执行下一个过滤器,没有则执行目标资源)
    chain.doFilter(request, response);
    System.out.println("FirstFilter的doFilter方法...放行之后" + this.hashCode());
  }

  //destroy: 销毁
  @Override
  public void destroy() {
    System.out.println("FirstFilter的destroy方法..." + this.hashCode());
  }
}

配置访问路径:

① 配置XML文件

  <!--配置过滤器-->
  <!--filter标签-->
  <filter>
    <filter-name>FirstFilter</filter-name>
    <filter-class>com.qf.web.filter.FirstFilter</filter-class>
  </filter>
  <!--filterMapping-->
  <filter-mapping>
    <filter-name>FirstFilter</filter-name>
    <!--拦截(过滤)路径-->
    <!--精确拦截-->
    <url-pattern>/welcome.jsp</url-pattern>
  </filter-mapping>

拦截路径:

  <!--filterMapping-->
  <filter-mapping>
    <filter-name>FirstFilter</filter-name>
    <!--精确拦截-->
    <url-pattern>/welcome.jsp</url-pattern>
    <!--后缀拦截-->
    <url-pattern>*.jsp</url-pattern>
    <!--通配符拦截  /aaa/* , /*-->
    <url-pattern>/images/*</url-pattern>
    <!--filter 不能用 /-->
  </filter-mapping>

配置参数:

  <filter>
      <init-param>
          <param-name>username</param-name>
          <param-value>张三</param-value>
      </init-param>
  </filter>

获取参数:

  //init :初始化方法
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("FirstFilter的init方法..." + this.hashCode());
    String username = filterConfig.getInitParameter("username");
    System.out.println(username);
  }

②注解配置

@WebFilter(filterName = "First",value = "/welcome.jsp",initParams = {@WebInitParam(name = "username",value = "李四")})
public class FirstFilter implements Filter {}

当XML与注解都配置,且是对同一个进行过滤时两个都会执行。执行顺序如下:

IDEA创建过滤器

若没有可以看看下面设置有没有点,打开的下面界面的快捷键Ctrl+Shift+S

@WebFilter(filterName = "SecondFilter",value = "/welcome.jsp")
public class SecondFilter implements Filter {
    @Override
    public void destroy() {
        System.out.println("SecondFilter的destroy方法..."+this.hashCode());
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("SecondFilter的doFilter方法...放行之前"+this.hashCode());
        chain.doFilter(req, resp);
        System.out.println("SecondFilter的doFilter方法...放行之前"+this.hashCode());
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("SecondFilter的init方法..."+this.hashCode());
    }
}

若用注解的方式创建的Filter,且对同一个进行过滤,执行的顺序按照过滤器名称字符串的顺序。

1.2.过滤器链

客户端对服务器发出请求,执行目标资源先执行多个过滤器,称之为过滤器链。

执行流程:

  • 当第一个Filter的doFilter方法被调用时,服务器会创建一个代表Filter链的chain对象传递给该方法。在doFilter方法中,如果调用了chain对象的doFilter方法,则服务器会检查chain对象中是否还有filter,如果有,则调用第二个filter,如果没有,则调用目标资源。

1.3Filter优先级

  • 若是XML配置的按由上到下的顺序。
  • 若是注解配置的按类名称字符串顺序。
  • XML配置高于注解的方式
  • 同时创建会创建多个过滤器对象

1.4 过滤器经典应用

1.禁止浏览器缓存动态页面

以前浏览器会使用缓存,有刷新不更新的问题。

方式一:以下标签禁用缓存。

  • <meta http-equiv=”pragma” content=”no-cache” />     //批注不缓存
  • <meta http-equiv=”cache-control” content=”no-cache” />    //缓存控制不缓存
  • <meta http-equiv=”expires” content=”0″ /> //过期时间0
<%@ page contentType="text/html;charset=UTF-8" language="java"
%>
<html>
  <head>
    <title>Title</title>
    <meta http-equiv="pragma" content="no-cache" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
  </head>
  <body>
    <h2>当前时间:<%=new Date().toString()%></h2>
  </body>
</html>

方式二:添加过滤器

@WebFilter("*.jsp")
public class NoCacheFilter implements Filter {

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws IOException, ServletException {
    //放行
    HttpServletResponse response = (HttpServletResponse) resp;
    response.setHeader("pragma", "no-cache");
    response.setHeader("cache-control", "no-cache");
    response.setDateHeader("expires", 0);
    chain.doFilter(req, resp);
  }

  @Override
  public void destroy() {
  }
}

设置缓存有效期:

@WebFilter(filterName = "CacheFilter", value = "*.jpg")
public class CacheFilter implements Filter {

  @Override
  public void destroy() {
  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws ServletException, IOException {
    HttpServletResponse response = (HttpServletResponse) resp;
    response.setHeader("cache-control", "max-age=600");//10分钟
    response.setDateHeader("expires", System.currentTimeMillis() + 600000);
    chain.doFilter(req, resp);
  }

  @Override
  public void init(FilterConfig config) throws ServletException {
  }
}


Click here to view the copyright notice of this site(点击此处查看本站版权声明)
0 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!