JavaWeb过滤器Filter

         Filter也称为过滤器,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制,页面的同一编码,过滤敏感词汇、压缩响应信息等一些高级功能!

         Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

         看一下filter中有哪些方法!

<span style="font-size:18px;">public class Demo1Filter implements Filter {
    //Filter 链的执行 
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
    }
    //Init 方法在 Filter 生命周期中仅执行一次,web 容器在调用 init 方法时
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    //在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
    public void destroy() {
    }
}
</span>

         我们先来看一下在访问资源的时候,他的执行过程!

     在我们的web容器启动时在 web 应用程序启动时,web 服务器将根据 web.xml 文件中的配置信息来创建每个注册的 Filter 实例对象,并将其保存在服务器的内存中。然后当用户用浏览器请求一个页面的时候, 会先向web的容器发送一个请求,然后web容器在根据请求去找相应的资源!在找资源的时候,会先经过Filter,然后在继续向后执行,一个应用程序中可以有多个filter!filter 的执行的顺序跟在web.xml文件中配置的顺序是一样的!

    下边我们通过一个实例来看一下filter是如何应用的!

    web.xml配置

 

<!-- 编码过滤器 -->   
    <filter>   
        <filter-name>setCharacterEncoding</filter-name>   
        <filter-class>com.company.strutstudy.web.servletstudy.filter.EncodingFilter</filter-class>   
        <init-param>   
            <param-name>encoding</param-name>   
            <param-value>utf-8</param-value>   
        </init-param>   
    </filter>   
    <filter-mapping>   
        <filter-name>setCharacterEncoding</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>   
    
<!-- 请求url日志记录过滤器 -->   
    <filter>   
        <filter-name>logfilter</filter-name>   
        <filter-class>com.company.strutstudy.web.servletstudy.filter.LogFilter</filter-class>   
    </filter>   
    <filter-mapping>   
        <filter-name>logfilter</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>  

编码拦截器:

public class EncodingFilter implements Filter {   
    private String encoding;   
    private Map<String, String> params = new HashMap<String, String>();   
    // 项目结束时就已经进行销毁   
    public void destroy() {   
        System.out.println("end do the encoding filter!");   
        params=null;   
        encoding=null;   
    }   
    public void doFilter(ServletRequest req, ServletResponse resp,   
            FilterChain chain) throws IOException, ServletException {   
        //UtilTimerStack.push("EncodingFilter_doFilter:");   
        System.out.println("before encoding " + encoding + " filter!");   
        req.setCharacterEncoding(encoding);   
        // resp.setCharacterEncoding(encoding);   
        // resp.setContentType("text/html;charset="+encoding);   
        chain.doFilter(req, resp);         
        System.out.println("after encoding " + encoding + " filter!");   
        System.err.println("----------------------------------------");   
        //UtilTimerStack.pop("EncodingFilter_doFilter:");   
    }   
    
    // 项目启动时就已经进行读取   
    public void init(FilterConfig config) throws ServletException {   
        System.out.println("begin do the encoding filter!");   
        encoding = config.getInitParameter("encoding");   
        for (Enumeration e = config.getInitParameterNames(); e   
                .hasMoreElements();) {   
            String name = (String) e.nextElement();   
            String value = config.getInitParameter(name);   
            params.put(name, value);   
        }   
    }   
 }  


日志拦截器:

public class LogFilter implements Filter {   
    FilterConfig config;   
    
    public void destroy() {   
        this.config = null;   
    }   
    
    public void doFilter(ServletRequest req, ServletResponse res,   
            FilterChain chain) throws IOException, ServletException {   
        // 获取ServletContext 对象,用于记录日志   
        ServletContext context = this.config.getServletContext();   
        //long before = System.currentTimeMillis();   
        System.out.println("before the log filter!");   
        //context.log("开始过滤");   
        // 将请求转换成HttpServletRequest 请求   
        HttpServletRequest hreq = (HttpServletRequest) req;   
        // 记录日志   
        System.out.println("Log Filter已经截获到用户的请求的地址:"+hreq.getServletPath() );   
        //context.log("Filter已经截获到用户的请求的地址: " + hreq.getServletPath());   
        try {   
            // Filter 只是链式处理,请求依然转发到目的地址。   
            chain.doFilter(req, res);   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
        System.out.println("after the log filter!");   
        //long after = System.currentTimeMillis();   
        // 记录日志   
        //context.log("过滤结束");   
        // 再次记录日志   
        //context.log(" 请求被定位到" + ((HttpServletRequest) req).getRequestURI()   
        //      + "所花的时间为: " + (after - before));   
    }   
    
    public void init(FilterConfig config) throws ServletException {   
        System.out.println("begin do the log filter!");   
        this.config = config;   
    }   
    
 }   


HelloServlet类:

public class HelloWorldServlet extends HttpServlet{   
    
    /**  
     * 查看httpservlet实现的service一看便知,起到了一个controll控制器的作用(转向的)  
     * 之后便是跳转至我们熟悉的doget,dopost等方法中   
     */   
    @Override   
    protected void service(HttpServletRequest req, HttpServletResponse resp)   
            throws ServletException, IOException {   
        System.out.println("doservice..."+this.getInitParameter("encoding"));   
           
        super.service(req, resp);   
    }   
    
    @Override   
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)   
            throws ServletException, IOException {   
        System.out.println("doget...");   
        doPost(req, resp);   
    }   
    
    @Override   
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)   
            throws ServletException, IOException {   
        System.out.println("dopost...");   
    }   


结果:

before encoding utf-8 filter!   
  before the log filter!   
  Log Filter已经截获到用户的请求的地址:/hello   
  doservice...UTF-8   
  doget...   
  dopost...   
  after the log filter!   
  after encoding utf-8 filter!   
  ----------------------------------------   

 

Filter生命周期

  Servlet一样Filter的创建和销毁也是由WEB服务器负责。不过与Servlet区别的是

    1>在应用启动的时候就进行装载Filter(Servletload-on-startup配置效果相同)

    2>容器创建好Filter对象实例后,调用init()方法。接着被Web容器保存进应用级的集合容器中去了等待着,用户访问资源。

    3>当用户访问的资源正好被Filterurl-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了)

    4>应用服务被停止或重新装载了,则会执行Filterdestroy方法,Filter对象销毁。

    注意:init方法与destroy方法只会直接一次。

   

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值