美文网首页java web
Java Web(6) 过滤器Filter

Java Web(6) 过滤器Filter

作者: loserwang_3030 | 来源:发表于2020-07-17 16:47 被阅读0次

    过滤器(Filter)是 J2EE Servlet模块性的组件。Filter的作用是对URL进行统一的拦截处理。Filter通常用于应用程序层面进行全局处理。

    1. 实现Filter

    开发过滤器三要素

    • 任何过滤器都要实现javax.servlet.Filter接口
    • 在 Filter接口的 doFilter()方法中编写过滤器的功能代码。
    • 在web.xml中对过滤器进行配置,说明拦截URL的范围

    接下来具体实现:

    • xml配置方式:
    public class FirstFilter implements Filter {
        public void destroy() {
    //...
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
           System.out.println("过滤器FirstFilter已生效");
           chain.doFilter(req,resp);
        }
    
        public void init(FilterConfig config) throws ServletException {
         //...
        }
    
    }
    
    <filter>
           <filter-name>First</filter-name>
           <filter-class>Filter.FirstFilter</filter-class>
       </filter>
        <filter-mapping>
            <filter-name>First</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    • 注解@WebFilter配置方式
    属性名 类型 描述
    filterName String 指定过滤器的 name 属性,等价于 <filter-name>
    value String[] 该属性等价于 urlPatterns 属性。但是两者不应该同时使用。
    urlPatterns String[] 指定一组过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。
    servletNames String[] 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 <servlet-name> 的取值。
    dispatcherTypes DispatcherType 指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。
    initParams WebInitParam[] 指定一组过滤器初始化参数,等价于 <init-param> 标签。
    asyncSupported boolean 声明过滤器是否支持异步操作模式,等价于 <async-supported> 标签。
    description String 该过滤器的描述信息,等价于 <description> 标签。
    displayName String 该过滤器的显示名,通常配合工具使用,等价于 <display-name> 标签。
    @WebFilter(filterName = "FirstFilter", urlPatterns = "/*")
    public class FirstFilter implements Filter { //...}
    

    2. 过滤器生命周期

    • 初始化 :Filter.init()服务器启动后
    • 提供服务 :Filter.doFilter()
    • 销毁 :Filter.destroy()服务器关闭前
      过滤器对象在Web应用启动时被创建且全局唯一。唯一的过滤器 对象在并发环境中采用”多线程“提供服务。

    3. 过滤器参数化

    过滤器为了增强灵活性,允许配置信息放在web.xml。在web.xml中配置<init-param>设置过滤器参数

    • xml方式
    <filter>
           <filter-name>First</filter-name>
           <filter-class>Filter.FirstFilter</filter-class>
            <init-param>
                  <param-name>encoding</param-name>
                  <param-value>UTF-8
            </init-param>
       </filter>
        <filter-mapping>
            <filter-name>First</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    public class FirstFilter implements Filter {
           String encoding;
             public void init(FilterConfig config) throws ServletException {
                    encoding =  config.getInitParameter("encoding");
              }
    ......
        }
    
    • 注解方式
    @WebFilter(filterName = "FirstFilter", urlPatterns = "/*",
            initParams = {
                    @WebInitParam(name = "encoding",value = "UTF-8"),
                    @WebInitParam(name = "P2",value = "V2")
            })
    public class FirstFilter implements Filter {
           String encoding;
             public void init(FilterConfig config) throws ServletException {
                    encoding =  config.getInitParameter("encoding");
              }
        }
    

    4. 过滤链

    过滤链
    过滤器的执行顺序以<filter-mapping>的顺序为准。调用chain.doFilter()将请求向后转递。
    • xml方式
    <filter>
           <filter-name>FilterA</filter-name>
           <filter-class>Filter.FilterA</filter-class>
       </filter>
        <filter-mapping>
            <filter-name>FilterA</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    <filter>
           <filter-name>FilterB</filter-name>
           <filter-class>Filter.FilterB</filter-class>
       </filter>
        <filter-mapping>
            <filter-name>FilterB</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    <filter>
           <filter-name>FilterC</filter-name>
           <filter-class>Filter.FilterC</filter-class>
       </filter>
        <filter-mapping>
            <filter-name>FilterC</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    public class FilterA implements Filter {
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
              System.out.println("A is printed")
               chain.doFilter(req,resp);
        }
    }
    public class FilterB implements Filter {
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
              System.out.println("B is printed")
               chain.doFilter(req,resp);
        }
    }
    public class FilterC implements Filter {
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
              System.out.println("C is printed")
               chain.doFilter(req,resp);
        }
    }
    public class FirstServlet extends HttpServlet {
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           System.out.println("Servlet is printed")
        }
    }
    
    

    输出:

    A is printed
    B is printed
    C  is printed
    Servlet is printed
    

    如果将输出语句位置调换

    public class FilterA implements Filter {
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
               chain.doFilter(req,resp);
               System.out.println("A is printed")
        }
    }
    

    输出:

    Servlet is printed
    C  is printed
    B is printed
    A is printed
    
    
    • 注解方式
      使用注解方式时,过滤链按照名称的字典顺序,很不合理。

    eg:字符集过滤器

    Web中文乱码的解决

    • GET请求 :server.xml增加URIEncoding="UTF-8"
    • POST请求 :使用request.setCharacterEncoding("UTF-8")
    • 响应 response.setContentType("text/html;charset=UTF-8")
    @WebFilter(filterName = "CharacterEncodingFilter")
    public class CharacterEncodingFilter implements Filter {
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
           //因为Tomcat中request的实现类继承自HttpServletRequest
            //所以可以转化为HttpServletRequest,以防ServletRequest不含有某些方法
            //详情见前面的 Java Web(3)HttpServletRequest和HttpServletResponse
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response =   (HttpServletResponse) resp;
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            chain.doFilter(request, response);
    
        }
    
        public void init(FilterConfig config) throws ServletException {
        }
    
    }
    

    相关文章

      网友评论

        本文标题:Java Web(6) 过滤器Filter

        本文链接:https://www.haomeiwen.com/subject/eecghktx.html