欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!
初识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开发,尽管已经有很多成熟的框架,封装已经相当娴熟,使得开发人员可以尽可能更贴近业务开发。但特例永远存在,无论何时,都不能避免业务需求场景的多样性。在框架无法解决问题时,最底层的技术实现或许可以帮到你,让你以更低的成本获得更好的效果。
若文中存在错误和不足,欢迎指正!
本博微信公众号“超哥说码”,欢迎大家订阅,公众号正在完善中,会及时将更优质的博文推送于您!