Filter : 过滤请求和响应

5次阅读

共计 2873 个字符,预计需要花费 8 分钟才能阅读完成。

filter 对象可以改变请求和响应的头信息和内容信息。过滤器和 web 组件的不同之处在于,过滤器通常不会自行创建响应。作为替代,过滤器提供附加到任意类型的 web 资源的功能。因此,过滤器不该对要过滤的 web 资源有任何依赖。这样,它可以由多种 web 资源组成。过滤器可以执行的主要任务如下:

查询请求并采取响应措施
组织请求 - 响应对的进一步传递
修改请求头和数据。你可以通过设置请求的自定义版本来完成此操作。
修改响应头和数据。你可以通过设置响应的自定义版本来完成此操作。
与 web 资源相互作用

应用程序的过滤器包含认证、日志、图片转换、数据压缩、数据加密、标记流、xml 转换等。你可以给一个 web 资源配置 0 - 多个过滤器,并且可以自定义过滤器的顺序。过滤器链在包含此组件的 web 资源部署时指定,并且在 web 容器加载的时候实例化。
编写 filter 程序
filtering api 定义在 javax.servlet 包中的 Filter, FilterChain, and FilterConfig 接口中。你可以通过实现 Filter 接口定义一个过滤器。使用 @WebFilter 注解在 web 程序中定义过滤器。这个注解作用在类上,并且包含过滤器的元数据。过滤器注解必须定义至少一个 url 匹配,通过使用 z 注解的 urlPatterns 或 value 属性完成这个操作。所有其他的属性都是可选的,有默认设置。当只有一个 url 规则时使用 value 注解;当有多个 url 规则或需要自定义属性时使用 urlPatterns 注解。使用 @WebFilter 注解的类必须实现 javax.servlet.Filter 接口。要将配置数据添加到过滤器中,可以使用 @WebFilter 注解的 initParams 属性。initParams 属性包含一个 @WebInitParam 注解。下面的代码片段定义了一个过滤器,定义了一个初始化参数:
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

@WebFilter(filterName = “TimeOfDayFilter”,
urlPatterns = {“/*”},
initParams = {
@WebInitParam(name = “mood”, value = “awake”)})
public class TimeOfDayFilter implements Filter {

Filter 接口的最重要的方法是 doFilter,这个方法可以执行下列操作:

核查请求头
定制请求对象,如果过滤器想要修改请求头或数据
定制响应对象,如果过滤器想要修改响应头或数据
调用过滤器链的下一个实体。如果当前过滤器是过滤器链的最后一个过滤器,并且结束目标是 web 资源或静态资源,下一个实体是链末端的资源;否则,下一个实体是 war 定义的过滤器。过滤器通过调用 chain 对象的 doFilter 方法调用下一个实体,传入调用它的请求、响应或它创建的包装版本。换种说法是,filter 可以通过不调用下一个实体来阻塞请求。在后一种情况下,过滤器负责填充响应。
在调用下一个实体后核查响应头
抛出一个错误指示执行流程中的错误

执行 doFilter,你必须实现 init 和 destroy 方法。init 方法在 web 容器实例化的时候调用;如果你想给 filter 传入初始化参数,可以通过传入 init 方法的 FilterConfig 参数获取它们。
编写自定义请求和响应代码
过滤器有多种方式去修改请求和响应。例如,一个过滤器可以向请求添加一个参数或者在响应中插入数据。过滤器修改响应必须在响应返回客户端之前捕获响应。为此,您将一个替代流传递给生成响应的 servlet。备用流阻止 servlet 在完成时关闭原始响应流,并允许过滤器修改 servlet 的响应。要将此替换流传递给 servlet,过滤器会创建一个响应包装器,它会覆盖 getWriter 或 getOutputStream 方法以返回此替换流。这个包装器通过过滤器链 doFilter 方法传递。包装器方法默认调用包装的请求或响应对象。重写请求方法,你包装的请求必须继承 ServletRequestWrapper 或 HttpServletRequestWrapper。重写响应方法,你的响应必须继承 ServletResponseWrapper or HttpServletResponseWrapper。
指定过滤器映射
web 容器使用请求映射决定给 web 资源应用具体的过滤器。过滤器映射使用名称映射一个过滤器到 web 组件或者使用 url 规则匹配到 web 资源。过滤器按照 war 中定义的顺序执行。您可以使用 NetBeans IDE 或使用 XML 手动编写列表来为其部署描述符中的 WAR 指定过滤器映射列表。如果你想记录每一个到 web 应用的请求,你可以将过滤器映射到 url 规则“/”。可以映射 filter 到一个或多个 web 资源,当然你也可以给一个 web 资源映射多个 filter。参见下图,F1 映射到 S1、S2、S3,F2 映射到 S2,F3 映射到 S1、S2. 再次强调,filter chain 是传入 filter 的 doFilter 方法的一个参数。该链通过过滤器映射间接生成。链中的过滤器顺序与过滤器映射在 Web 应用程序部署描述符中的显示顺序相同。当一个过滤器映射到 S1,web 容器调用 F1 的 doFilter 方法。S1 的过滤器链中每个过滤器的 doFilter 方法由链中的前一个过滤器通过 chain.doFilter 方法调用。因为 S1 的过滤器链包含过滤器 F1 和 F3,所以 F1 对 chain.doFilter 的调用会调用过滤器 F3 的 doFilter 方法。当 F3 的 doFilter 方法完成时,控制返回 F1 的 doFilter 方法。
通过 NetBeans IDE 定义请求映射

在 Project 节点展开应用程序
展开 Project 节点下的 Web Pages and WEB-INF 节点
双击 web.xml
点击编辑窗口最上方的 Filters
展开编辑窗口的 Servlet Filters 节点
点击 Add Filter Element 添加 filter 与 web 资源的 url 映射关系
在添加 servlet filter 接口,填写 filtername
点击 Browse 定位 filter 适用的 servlet
点击 ok
要约束过滤器应用于请求的方式,步骤如下:

a. 展开 Filter Mappings 节点 b. 从 filterlist 中选择一个 filterc. 点击 addd. 在添加映射弹窗,需要选择一个转发类型:

REQUEST:只映射直接从客户端过来的请求
ASYNC:只映射直接从客户端过来的的异步 async 请求
FORWARD:只有当请求被转发到组件时
INCLUDE:仅当请求由已包含的组件处理时
ERROR:仅在使用错误页面机制处理请求时

通过选择多个调度程序类型,可以指示过滤器应用于上述情况的任意组合。如果未指定类型,则默认选项为 REQUEST

正文完
 0