Servlet 中的 Filter 过滤器回顾

2017-07-08 From 程序之心 By 丁仪

Filter 是 Servlet 技术中的过滤器。在 Servlet 提供服务的过程中,Filter 用于对资源请求的拦截和处理,在请求到达 Servlet 之前可以处理请求头和数据,在响应返回给客户端之前可以修改返回头和数据,如实现登录控制、对特定的 URL 进行处理、过滤关键词、修改返回结果等。使用 Filter 进行处理,可以综合多个过滤器做复杂的过滤操作,并且过滤逻辑业务逻辑解耦易于扩展和优化。

Filter 接口定义

javax.servlet.Filter 接口定义了 3 个方法,如下所示:

public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
public void destroy();

其中:

init 方法用于初始化,参数为 FilterConfig 对象,FilterConfig 对象存储了 web.xml 中 Filter 的配置。

doFilter 方法用于实现 Filter,参数为 ServletRequest 、ServletResponse 和 FilterChain,分别表示请求对象、响应对象和 Filter 链。用户在这个方法中实现对请求和响应的处理,通过调用 FilterChain 的 doFilter 方法传递请求给下一个 Filter。

destroy 方法用于销毁,只被调用一次,调用此方法后 Servlet 容器不会再继续调用 doFilter 方法。用户可以在这个方法中释放占用的资源。

FilterConfig 接口定义了 Filter 的实现类需要实现的方法,如下所示。Servlet 容器初始化 Filter 时调用 init 方法传入 FilterConfig,Filter 可以从 FilterConfig 中获取相关的配置信息,如 Filter 的名称、Servlet 上下文XML 中配置的初始化参数等。

public String getFilterName(); //返回filter的名称 
public ServletContext getServletContext();//获取Servlet的上下文 
public String getInitParameter(String name);//获取初始化参数的值 
public Enumeration<String> getInitParameterNames();//获取初始化参数名称枚举集合

Filter 接口的 doFilter 方法传入了一个 Filter 链 FilterChain,可以配置多个 Filter 来实现复杂的过滤功能,利用责任链模式完成处理。FilterChain 接口只有一个方法,就是 doFilter 方法,执行该方法之前,属于对请求进行处理,执行该方法之后,属于对响应进行处理

public void doFilter ( ServletRequest request, ServletResponse  response ) throws IOException, ServletException;

Servlet 容器根据 XML 中的配置顺序,决定 Filter 的调用顺序,在调用 Filter 时生成调用链传给 Filter。一个 Filter 直接调用 FilterChain 的 doFilter 方法即可进入下一个 Filter;如果调用链已经调用完毕,Servlet 容器就会开始处理 Servlet 的流程,也就是说从 Filter 到 Servlet 的跳转是自动完成的。

Filter 配置

Servlet 类似,在 web.xml 中使用 filter 节点和 filter-mapping 节点配置 Filter。在 filter 节点中,可以配置名称、实现类、描述和初始化参数。在 filter-mapping 节点可以配置关联的 URL 和 Servlet 名称,以及调度方式。

<filter> 
  <filter-name>名称</filter-name> 
  <filter-class>实现类</filter-class> 
  <description>描述</description> 
  <init-param> 
    <param-name>参数名称</param-name> 
    <param-value>参数值</param-value> 
  </init-param> 
</filter> 
<filter-mapping> 
  <filter-name>名称</filter-name> 
  <url-pattern>URL匹配规则</url-pattern> 
  <servlet-name>Servlet 名称</servlet-name> 
  <dispatcher>调度</dispatcher> 
</filter-mapping>

dispatcher 可以有零或多个,可选值有 REQUEST 、INCLUDE 、FORWARD 或者 ERROR,默认值为 REQUEST。含义如下:

REQUEST:仅在当用户直接访问页面时调用过滤器。如果目标资源是通过 RequestDispatcher 的 include 或 forward 方法访问时,那么该过滤器就不会被调用。

INCLUDE:如果目标资源是通过 RequestDispatcher 的 include 方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

FORWARD:如果目标资源是通过 RequestDispatcher 的 forward 方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

Filter 与 Servlet 的区别

Filter 对用户请求进行处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对响应进行处理然后返回给客户端。因此 Filter 不能像 Servlet 那样生成返回给客户端的响应,只能对请求和响应进行过滤修改。

一个 Filter 处理完流程后,可以交给下一个 Filter 处理或交给 Servlet 处理;但是一个 Servlet 处理完流程后,请求不会再继续传递下去。因此有些处理逻辑放在 Filter 中更合适,比如请求响应日志、关键词过滤等,可以使得 Servlet业务流程更简单。

本文来源:程序之心,转载请注明出处!

本文地址:https://chengxuzhixin.com/blog/article/200035.html

发表感想

© 2016 - 2022 chengxuzhixin.com All Rights Reserved.

浙ICP备2021034854号-1    浙公网安备 33011002016107号