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页面。只有当用户登录该应用后才可自由访问其他页面。