2.9.2 配置Filter
2.9.2 配置Filter
前面已经提到,Filter
可以认为是Servlet
的“增强版”,因此配置Filter
与配置Servlet
非常相似,都需要配置如下两个部分。
- 配置
Filter
名 - 配置
Filter
拦截URL
模式。
区别在于:Servlet
通常只配置一个URL
,而Filter
可以同时拦截多个请求的URL
。因此,在配置Filter
的URL
模式时通常会使用模式字符串,使得Filter
可以拦截多个请求。
与配置Servlet
相似的是,配置Filter
同样有两种方式。
- 在
Filter
类中通过注解进行配置。 - 在
web.xml
文件中通过配置文件进行配置。
上面Filter
类的粗体字代码使用@WebFilter
配置该Filter
的名字为log
,它会拦截向/*
发送的所有的请求。
@WebFilter注解属性
@WebFilter
修饰一个Filter
类,用于对Filter
进行配置,它支持如表2.3所示的常用属性。
属性 | 说明 |
---|---|
asyncSupported |
指定该Filter 是否支持异步操作模式。关于Filter 的异步调用请参考2.12节 |
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
与配置Servlet
非常相似,需要为Filter
指定它所过滤的URL
,并且也可以为Filter
配置参数
如果不使用注解配置该Filter
,则可换成在web.xml
文件中为该Filter
增加如下配置片段:
1 | <!-- 定义Filter --> |
上面的粗体字代码用于配置该Filter
,从这些代码中可以看出配置Filter
与配置Servlet
非常相似,只是配置Filter
时指定url-Pattern
为/*
,即表示该Filter
会拦截所有用户请求。该Filter
并未对客户端请求进行额外的处理,仅仅在日志中简要记录请求的信息。
为该Web
应用提供任意一个JSP
页面,并通过浏览器来访问该JSP
页面,即可在Tomcat
的控制台看到如图2.39所示的信息。
实际上Filter
和Servlet
极其相似,区别只是Filter
的doFilter()
方法里多了一个FilterChain
的参数,通过该参数可以控制是否放行用户请求。在实际项目中,Filter
里doFilter()
方法里的代码就是从多个Servlet
的service()
方法里抽取的通用代码,通过使用Filter
可以实现更好的代码复用。
假设系统有包含多个Servlet
,这些Servlet
都需要进行一些的通用处理:
比如权限控制、记录日志等,这将导致在这些Servlet
的service()
方法中有部分代码是相同的,为了解决这种代码重复的问题,可以考虑把这些通用处理提取到Filter
中完成,这样各Servlet
中剩下的只是特定请求相关的处理代码,而通用处理则交给Filter
完成。图2.40显示了Filter
的用途。
由于Filter
和Servlet
如此相似,所以Filter
和Servlet
具有完全相同的生命周期行为,且Filter
也可以通过<init-param>
元素或@WebFilter
的initParams
属性来配置初始化参数,获取Filter
的初始化参数则使用FilterConfig
的getInitParameter()
方法。
下面将定义一个较为实用的Filter
,该Filter
对用户请求进行过滤,Filter
将通过doFilter()
方法来设置request
编码的字符集,从而避免每个JSP
、Servlet
都需要设置;而且还会验证用户是否登录,如果用户没有登录,系统直接跳转到登录页面。
下面是该Filter
的源代码
1 | package lee; |
上面Filter
的doFilter()
方法开始的三行代码:
1 | String encoding = config.getInitParameter("encoding"); |
用于获取Filter
的配置参数,
代码:
1 | request.setCharacterEncoding(encoding); |
按配置参数设置了request
编码所用的字符集.
接下来的代码:
1 | if( session.getAttribute("user") == null |
判断session
范围内是否有user
属性——没有该属性即认为没有登录,如果既没有登录,而且请求地址也不是登录页和处理登录页,系统直接跳转到登录页面。
通过@WebFilter
的initParams
属性可以为该Filter
配置初始化参数,@WebFilter
的initParams
属性可以接受多个@WebInitParam
,每个@WeblnitParam
指定一个初始化参数。
web.xml中为Filter配置参数
在web.xml
文件中也使用<init-param>
元素为该Filter
配置参数,与配置Servlet
初始化参数完全相同。
如果不使用注解配置该Filter
,打算在web.xml
文件中配置该Filter
,则该Filter
的配置片段如下:
1 | <!-- 定义Filter --> |
上面的配置片段中粗体字代码为该Filter
指定了三个配置参数,指定loginPage
为/login.jsp
,ProLogic
为/proLogin.jsp
,这表明,如果没有登录该应用,普通用户只能访问/login.jsp
和/proLogin.jsp
页面。只有当用户登录该应用后才可自由访问其他页面。