Filter

作者: 虫儿飞ZLEI | 来源:发表于2018-08-10 11:02 被阅读0次

    layout: post
    title: Filter
    subtitle: 用法
    date: 2018-04-28
    author: ZL
    header-img: img/20180428.jpg
    catalog: true
    tags:
    - Filter


    Filter

    说明

    Filter叫做过滤器,对客户端访问的资源进行过滤。
    就好像是一道墙,隔在客户端和服务器资源之间,要访问服务器资源,先进入到filter之中,在filter中决定是否放行,如果放行了,就可以访问到服务器的某个资源,不放行的话就无法访问。

    创建与销毁的时间

    Filter何时创建:服务器启动时就创建该filter对象
    Filter何时销毁:服务器关闭时filter销毁

    代码实例

    步骤:

    • 编写一个过滤器的类实现Filter接口
    • 实现接口中尚未实现的方法(着重实现doFilter方法)
    • 在web.xml中进行配置(主要是配置要对哪些资源进行过滤)

    Filter

    package com.ithiema.web.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    
    public class QuickFilter1 implements Filter{
        
        @Override
        //Filter创建的时候执行init方法
        public void init(FilterConfig filterConfig) throws ServletException {
            //1、获得web.xml中filter 的名称<filter-name>QuickFilter1</filter-name>
            System.out.println(filterConfig.getFilterName());
            //2、获得当前filter的初始化参数
            System.out.println(filterConfig.getInitParameter("aaa"));
            //3、获得servletContext
            filterConfig.getServletContext();
            
            System.out.println("init ....");
        }
    
        @Override
        //doFilter是Filter的核心过滤的方法
        /*
         * request: 内部封装是客户端http请求的内容
         * response: 代表是响应
         * FilterChain: 过滤器链对象
         */
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            
            System.out.println("quick1 running....");
            //放行请求
            chain.doFilter(request, response);
        }
    
        @Override
        //Filter对象销毁的时候执行destory方法
        public void destroy() {
            System.out.println("destroy...");
        }
    
    }
    

    web.xml配置

    <filter>
      <filter-name>QuickFilter1</filter-name>
      <filter-class>com.ithiema.web.filter.QuickFilter1</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>QuickFilter1</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    Filter的API

    主要有这么几个方法

    @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() {
      
    }
    
    • init(FilterConfig)
      其中参数config代表 该Filter对象的配置信息的对象,内部封装是该filter的配置信息。

      image
    • destory()方法
      filter对象销毁时执行

    • doFilter方法
      doFilter(ServletRequest,ServletResponse,FilterChain)
      其中的参数:
      ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。
      FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
      //放行代码,只有放行了才可以访问资源
      chain.doFilter(request, response);
      

    web.xml的配置

    Filter必须要配置了才会起作用,配置了让filter和资源配对,访问不同的资源有不同的filter对应。

    <filter>
      <filter-name>EncodingFilter</filter-name>
      <filter-class>com.ithiema.web.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>EncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    配置方式和servlet的配置方式差不多

    url-pattern配置

    • 完全匹配 /sertvle1
    • 目录匹配 /aaa/bbb/* ----最多的
      /user/:访问前台的资源进入此过滤器
      /admin/
      :访问后台的资源时执行此过滤器
    • 扩展名匹配 *.abc *.jsp

    dispatcher(不重要)

    <dispatcher>EncodingFilter</dispatcher>
    这个也是web.xml配置的一个条目,默认没有写表示REQUEST

    • REQUEST:默认值,代表直接访问某个资源时执行filter
    • FORWARD:转发时才执行filter
    • INCLUDE: 包含资源时执行filter
    • ERROR:发生错误时 进行跳转是执行filter

    Filter的作用

    • 公共代码的提取
    • 可以对request和response中的方法进行增强(装饰者模式/动态代理)
    • 进行权限控制

    比如:

    package com.ithiema.web.filter;
    
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    public class EncodingFilter implements Filter{
    
        
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            
            //request.setCharacterEncoding("UTF-8");
            
            //在传递request之前对request的getParameter方法进行增强
            /*
             * 装饰者模式(包装)
             * 
             * 1、增强类与被增强的类要实现统一接口
             * 2、在增强类中传入被增强的类
             * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的
             * 
             */
            
            //被增强的对象
            HttpServletRequest req = (HttpServletRequest) request;
            //增强对象
            EnhanceRequest enhanceRequest = new EnhanceRequest(req);
            
            
            chain.doFilter(enhanceRequest, response);
            
        }
    
        @Override
        public void destroy() {
            
        }
        
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            
        }
    
    }
    
    class EnhanceRequest extends HttpServletRequestWrapper{
        
        private HttpServletRequest request;
    
        public EnhanceRequest(HttpServletRequest request) {
            super(request);
            this.request = request;
        }
        
        //对getParaameter增强
        @Override
        public String getParameter(String name) {
            String parameter = request.getParameter(name);//乱码
            try {
                parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return parameter;
        }
        
    }
    
    <filter>
      <filter-name>EncodingFilter</filter-name>
      <filter-class>com.ithiema.web.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>EncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    这个EncodingFilter配置的/*,表示访问任何资源都会先过一遍这个EncodingFilter。
    从EncodingFilter类的代码可以看到,它的作用就是解决乱码的问题,这样子就全局的解决了乱码的问题,而不用在每一个servlet中去解决乱码。

    系统中解决乱码的filter,20181109追加

        <filter>
            <filter-name>encoding</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>utf-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    

    相关文章

      网友评论

          本文标题:Filter

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