Servlet规范系列 之 Filter源码分析

欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!

  初识Filter

  Filter,即过滤器,在客户端和服务端间承担请求和响应过滤处理的角色。至于使用Filter的原因,开发的小伙伴可能已经达成共识,在Filter中,可以进行通用性的过滤处理。

​  客户端到服务端方向的过滤器,可以承担:URL权限校验及过滤、Http Method权限控制、请求数据过滤转换等等。只要是HttpServletRequest承载的信息,都可以作为过滤处理的依据。

  服务端到客户端方向的过滤器,可以承担:过滤数据敏感词汇、编码响应数据、压缩响应信息、统一处理地址重定向等等。只要是HttpServletResponse承载的信息,都可以作为过滤处理的依据。

  Filter流程

   客户端发送请求,HttpServletRequest(请求)到达Servlet之前,过滤器拦截到客户端的HttpServletRequest。

   根据业务需求,配合HttpServletRequest的数据项,进行过滤处理,此时也可以修改HttpServletRequest头信息和有效负载内容。

   过滤器对HttpServletRequest处理完成之后,会调用doFilter方法,放行请求,此时请求会在过滤器链上向下传播,如果过滤器链已到末尾,那么请求会到达Servlet,Servlet对HttpServletRequest进行处理,同时产生HttpServletResponse并发送给客户端。

   HttpServletResponse(响应)到达客户端之前,过滤器拦截到响应的HttpServletResponse。

   根据业务需求,配合HttpServletResponse的数据项,进行过滤处理,此时也可以修改HttpServletResponse头信息和有效负载内容。

   最后,HttpServletResponse经传输到达客户端。

  Filter

  Filter生命周期:

  Servlet容器启动时,会创建Filter的实例对象,并调用其init方法,完成对象的初始化功能。Filter对象只创建一次,init方法也只会执行一次。

package javax.servlet;

import java.io.IOException;

/**
 * 过滤器是一个对象,它对资源的请求(servlet或静态内容)或来自资源的响应执行筛选任务,或同时执行这两个任务. 
 * 过滤器在doFilter方法中执行过滤.
 * 每个过滤器都可以访问FilterConfig对象,从中可以获得初始化参数,ServletContext的引用可以用来加载筛选任务所需的资源.
 */
public interface Filter {
    
    

    /**
     * 由web容器调用,以向筛选器指示正在将其置于服务中。在实例化过滤器之后,servlet容器只调用init方法一次. 
     * 在要求筛选器执行任何筛选工作之前,init方法必须成功完成.
     * @param filterConfig FilterConfig对象.
     * @throws ServletException .
     */
    public void init(FilterConfig filterConfig) throws ServletException;

    /**
     * 每次由于客户机请求链末端的资源而使请求/响应对通过链时,容器都会调用筛选器的doFilter方法. 
     * 传入此方法的FilterChain允许筛选器将请求和响应传递给链中的下一个实体.
     * @param request ServletRequest对象.
     * @param response ServletResponse对象.
     * @param chain FilterChain对象.
     * @throws IOException .
     * @throws ServletException .
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;

    /**
     * 由web容器调用,以向筛选器指示正在停止服务。只有在筛选器的doFilter方法中的所有线程都已退出或在超时时间过后,才会调用此方法. 
     * 在web容器调用此方法后,它将不再在此筛选器实例上调用doFilter方法.
     */
    public void destroy();

}

  FilterChain

  一组过滤器对某些web资源进行拦截,那么这组过滤器就称为过滤器链。过滤器的执行顺序和有关(谁在前先执行谁)。

package javax.servlet;

import java.io.IOException;

/**
 * FilterChain是servlet容器提供给开发人员的一个对象,它向开发人员提供了对资源的过滤请求的调用链的视图. 
 * 过滤器使用过滤器链调用链中的下一个过滤器,或者如果调用过滤器是链中的最后一个过滤器,则调用链末端的资源.
 */
public interface FilterChain {
    
    

    /**
     * 调用链中的下一个筛选器,或者如果调用筛选器是链中的最后一个筛选器,则会导致调用链末尾的资源.
     * @param request ServletRequest对象.
     * @param response ServletResponse对象.
     * @throws IOException .
     * @throws ServletException .
     */
    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;

}

  FilterConfig

  用户在配置Filter时,可以使用标签为Filter配置初始化参数,当Servlet容器创建Filter对象并调用其init方法时,会把初始化参数封装在FilterConfig对象并传递进来。

package javax.servlet;

import java.util.Enumeration;

/**
 * 过滤器配置对象,由servlet容器在初始化期间将信息传递给过滤器.
 */
public interface FilterConfig {
    
    

	/**
	 * 获取过滤器名称.
	 * @return 过滤器名称.
	 */
	public String getFilterName();

	/**
	 * 获取ServletContext对象.
	 * @return ServletContext对象.
	 */
    public ServletContext getServletContext();
    
    /**
     * 根据指定参数名获得参数值.
     * @param name 参数名.
     * @return 参数值.
     */
    public String getInitParameter(String name);

    /**
     * 获取过滤器所有参数,结果存放在Enumeration中.
     */
    public Enumeration getInitParameterNames();

}

  总结

  当前Web开发,尽管已经有很多成熟的框架,封装已经相当娴熟,使得开发人员可以尽可能更贴近业务开发。但特例永远存在,无论何时,都不能避免业务需求场景的多样性。在框架无法解决问题时,最底层的技术实现或许可以帮到你,让你以更低的成本获得更好的效果。

  若文中存在错误和不足,欢迎指正!

本博微信公众号“超哥说码”,欢迎大家订阅,公众号正在完善中,会及时将更优质的博文推送于您!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/securitit/article/details/108088920