zoukankan      html  css  js  c++  java
  • Filter基础知识

    一、简介

    作用:对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理的前后实现一些特殊的功能。

    过滤器 API:Filter,FilterChain,FilterConfig。

    Filter 程序:实现了 Filter 接口的 Java 类,由Servlet容器进行调用和执行,需要在 web.xml 中进行注册和设置它所能拦截的资源。

    原理:Filter可以对Servlet容器发送给Servlet程序的请求和Servlet程序回送给Servlet容器的响应进行拦截。可以决定是否将请求继续传递给Servlet程序,以及对请求和响应信息是否进行修改。

    二、使用方法

    1)void init(FilterConfig filterConfig)

    作用:类似于 Servlet 的 init 方法。在创建 Filter 对象(Filter 对象在 Servlet 容器加载当前 WEB 应用时即被创建)后,立即被调用, 且只被调用一次。该方法用于对当前的 Filter 进行初始化操作。Filter 实例是单例的。

    • FilterConfig 类似于 ServletConfig
    • 可以在 web.xml 文件中配置当前 Filter 的初始化参数. 配置方式也和 Servlet 类似。

    2)void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

    作用:真正 Filter 的逻辑代码需要编写在该方法中。每次拦截都会调用该方法。

    参数:FilterChain:Filter 链。多个 Filter 可以构成一个 Filter 链。

    • chain.doFilter(ServletRequest request, ServletResponse response):把请求传给 Filter 链的下一个 Filter,若当前 Filter 是 Filter 链的最后一个 Filter,将把请求给到目标 Serlvet(或 JSP)。
    • 多个 Filter 拦截的顺序和 <filter-mapping> 配置的顺序有关,靠前的先被调用。

    3)public void destroy()

    释放当前 Filter 所占用的资源的方法。在 Filter 被销毁之前被调用,且只被调用一次。

    public class HelloFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 
    throws IOException, ServletException {//放行 chain.doFilter(request, response); } @Override public void destroy() { } }

    web.xml

    url-pattern:指定该 Filter 可以拦截哪些资源,即可以通过哪些 url 访问到该 Filter。

    <dispatcher>:指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截

    • REQUEST:当用户直接访问页面时,Web 容器将会调用过滤器。如果目标资源是通过 RequestDispatcher 的 include() 或 forward() 方法访问时,那么该过滤器就不会被调用。通过 GET 或 POST 请求直接访问。
    • FORWARD:如果目标资源是通过 RequestDispatcher 的 forward() 方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。或 <jsp:forward page="/..." /> 或 通过 page 指令的 errorPage 转发页面. <%@ page errorPage="test.jsp" %>
    • INCLUDE:如果目标资源是通过 RequestDispatcher 的 include() 方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。或 <jsp:include file="/..." />
    • ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。在 web.xml 文件中通过 error-page 节点进行声明:
      <error-page>
          <exception-type>java.lang.ArithmeticException</exception-type>
          <location>/test.jsp</location>
      </error-page>
    <!-- 注册 Filter -->
    <filter>
        <filter-name>helloFilter</filter-name> 
        <filter-class>com.atguigu.javaweb.HelloFilter</filter-class>
    </filter>
    
    <!-- 映射 Filter -->
    <filter-mapping>
        <filter-name>helloFilter</filter-name>
        <url-pattern>/test.jsp</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    三、应用

    1. 使浏览器不缓存页面的过滤器

    有3个HTTP响应头字段都可以禁止浏览器缓存当前页面

    • HttpServletResponse.setDataHeader("Expires", -1);
    • HttpServletResponse.setHeader("Cache-Control", "no-cache");
    • HttpServletResponse.setHeader("Pragma", "no-cache");
    //HttpFilter的实现与HttpServlet相似
    public
    class NoCacheFilter extends HttpFilter { @Override public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { response.setDateHeader("Expires",-1); response.setHeader("Cache-Control","no-cache"); response.setHeader("Pragma","no-cache"); filterChain.doFilter(request, response); } }

    2. 字符编码的过滤器

    目标:让所有的页面都不会出现字符编码问题,为此需要添加一个过滤器

    EncodingFilter.java

    public class EncodingFilter extends HttpFilter{
    
        private String encoding;
        
        @Override
        protected void init() {
            encoding = getFilterConfig().getServletContext().getInitParameter("encoding");
        }
        
        @Override
        public void doFilter(HttpServletRequest request,
                HttpServletResponse response, FilterChain filterChain)
                throws IOException, ServletException {
            System.out.println(encoding); 
            request.setCharacterEncoding(encoding);
            filterChain.doFilter(request, response);
        }
    }

    web.xml

     <context-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
     </context-param>
     <filter>
          <filter-name>encodingFilter</filter-name>
          <filter-class>com.atguigu.javaweb.encoding.EncodingFilter</filter-class>
     </filter>
      
     <filter-mapping>
          <filter-name>encodingFilter</filter-name>
          <url-pattern>/*</url-pattern>
     </filter-mapping>
  • 相关阅读:
    编译安装MongoDB C++ Driver (win8.1 vs2013)
    Convert Sorted Array to Binary Search Tree
    Sqrt(x) 牛顿迭代法
    Sublime Text 2 新建C++ build system
    Add Two Numbers
    Two Sum *
    从TCP协议的原理来谈谈rst复位攻击
    【转载】专访阿里陶辉:大规模分布式系统、高性能服务器设计经验分享
    一个低级Illegal instruction错误的定位--忽略编译期警告就得加倍偿还
    【转载】“惊群”,看看nginx是怎么解决它的
  • 原文地址:https://www.cnblogs.com/CComma/p/7203330.html
Copyright © 2011-2022 走看看