Filter可认为是Servlet的“加强版”,主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。Filter也可以对用户请求生成相应,这一点与Servlet相同,但实际上很少会这样使用。使用Filter的完整流程是:Filter对用户的请求进行预处理,接着将请求交给Servlet进行处理并响应生成,最后Filter在对服务器响应进行后处理。
1. Filter有如下几个用处:
-
在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest
-
根据需要,检查HttpServletRequest,也可以修改HttpServletRequest的头和数据
-
在HttpServletResponse到达客户端之前,拦截HttpServletResponse
-
根据需要,检查HttpServletResponse,也可以修改HttpServletResponse的头和数据
2. Filter有如下几个种类:
-
用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户的非法请求,通常用于权限管理。
-
日志Filter:详细记录某些特殊的用户请求
-
负责解码的Filter:包括对非标准编码的请求解码
-
能改变XML内容的XSLT Filter等
3. 创建一个Filter只需两个步骤:
1). 创建Filter处理类 2). 在web.xml文件中配置Filter
3.1 创建Filter处理类
创建Filter必须实现javax.servlet.Filter接口,在该接口中定义了如下三个方法:
-
void init(FilterConfig config):用于完成Filter的初始化
-
void destroy():用于Filter销毁钱,完成某些资源的回收
-
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain):实现过滤功能,该方法就是对每个请求及响应增加的额外处理
下面是一个日志Filter,它负责拦截所有的用户请求,并将请求的信息记录在日志中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@WebFilter
(filterName=
"log"
, urlPatterns={
"/*"
}, initParams={
//这里使用注解的方式配置Filter
@WebInitParam
(name=
"encoding"
value=
"UTF-8"
),
@WebInitParam
(name=
"loginPage"
value=
"/login.jsp"
)
})
public
class
LogFilter
implements
Filter {
private
FilterConfig config;
//FilterConfig可用于访问Filter的配置信息
public
void
init(FilterConfig config) {
this
.config = config; }
public
void
destroy(){
this
.config =
null
;}
public
void
doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws
IOException, ServletException{
//下面的代码用于对用户请求执行预处理
ServletContext context =
this
.config.getServletContext();
//获取ServletContext对象,用于记录日志
long
before = System.currentTimeMillis();
System.out.println(
"开始过滤..."
);
HttpServletRequest request = (HttpServletRequest)req;
System.out.println(
"已经拦截到用户的请求地址:"
+ request.getServletPath());
chain.doFilter(req, resp);
//Filter只是链式处理,请求依然放行到目的地址
//下面的代码用于对服务器响应执行后处理
long
after = System.currentTimeMillis();
System.out.println(
"过滤结束"
);
System.out.println(
"请求被定位到:"
+ request.getRequestURI() +
" 耗时:"
+ (after - before));
//这里只是输出提示信息
}
}
|
上面的代码实现了doFilter()方法,实现该方法可以实现对用户请求的预处理,也可实现对服务器响应的后处理,它们的分界线为是否调用了chain.doFilter()方法,在这之前的是对用户请求的预处理,在这之后的,是对服务器响应的后处理。当Filter对请求过滤后,依然将请求发送到目的地址。如果需要检查权限,可以在Filter中根据用户请求的HttpSession,判断用户权限是否足够。如果权限不足,直接调用重定向即可,无需调用chain.doFilter()方法。
3.2 配置Filter
Filter在web.xml中的配置和Servlet在web.xml中的配置很相似,区别在于:一个Servlet通常只配置一个URL,而Filter可以同时拦截多个请求的URL,因此在配置Filter的urlPatterns时,通常会使用模式字符串,使得Filter可以拦截多个请求。和Servlet相似的是,配置Filter同样有两种方式:1). 在Filter类中通过注解进行配置 2). 在web.xml文件中进行配置
@WebFilter支持的常用属性介绍:
-
asyncSupported:指定该Filter是否支持异步操作模式
-
dispatcherTypes:指定该Filter仅对那种dispatcher模式的请求进行过滤。该属性支持ASYNC, ERROR, FORWARD, INCLUDE, REQUEST这5个值的任意组合,默认值为同时过滤这5中模式的请求
-
displayName:指定该Filter的显示名
-
filterName:指定该Filter的名称
-
initParams:用于为该Filter配置参数
-
servletNames:该属性可以指定多个Servlet名称,用于指定该Filter仅对这些Servlet进行过滤
-
urlPatterns/value:这两个属性的作用完全相同,用于指定该Filter所拦截的URL
下面是一个在web.xml中配置Filter的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
filter
>
<
filter-name
>log</
filter-name
>
<!-- 此属性相当于@WebFilter中的filterName属性 -->
<
filter-class
>com.abc.LogFilter</
filter-class
>
<!-- Filter的实现类 -->
<
init-param
>
<
param-name
>encoding</
param-name
>
<
param-value
>UTF-8</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>loginPage</
param-name
>
<
param-value
>/login.jsp</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>log</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
<!-- 负责拦截所有的URL,相当于@WebFilter中的urlPatterns属性 -->
</
filter-mapping
>
|