在web.xml中进行配置,对所有的url请求进行过滤,就像"击鼓传花"一样,链式处理。
配置分为两种a和b。
a:普通配置
在web.xml中增加如下内容:
<filter>
<filter-name>permissionfilter</filter-name>
<filter-class>com.taobao.riskm.filter.permissionfilter</filter-class>
</filter>
<filter-mapping>
<url-pattern>/*</url-pattern>
</filter-mapping>
由filter和filter-mapping构成。filter指定过滤器处理类(实现了filter接口),filter-mapping指定过滤的规则。
b:高级配置(允许代理注入spring bean)
<filter-name>permission</filter-name>
<filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class>
<init-param>
<param-name>targetfilterlifecycle</param-name>
<param-value>true</param-value>
</init-param>
<filter-mapping>
<url-pattern>*.htm</url-pattern>
在spring bean配置中加入:
<bean id="permission" class="com.taobao.kfc.kwb.web.permission.permissionhttpservlet"></bean>
因为filter比bean先加载,也就是spring会先加载filter指定的类到container中,这样filter中注入的spring bean就为null了。
解决办法:
先filter中加入delegatingfilterproxy类,"targetfilterlifecycle"指明作用于filter的所有生命周期。
原理是,delegatingfilterproxy类是一个代理类,所有的请求都会首先发到这个filter代理,然后再按照"filter-name"委派到spring中的这个bean。
在spring中配置的bean的name要和web.xml中的<filter-name>一样.
此外,spring bean实现了filter接口,但默认情况下,是由spring容器来管理其生命周期的(不是由tomcat这种服务器容器来管理)。如果设置"targetfilterlifecycle"为true,则spring来管理filter.init()和filter.destroy();若为false,则这两个方法失效!!
b和a最大的不同是,a是一个filter,优先被加载到container中,无法调用spring中后续的bean;而b是一个spring bean,可以引用其他的bean,而请求都通过delegatingfilterproxy类委派给b!
b的另外一种配置方式:
<param-name>targetbeanname</param-name>
<param-value>spring-bean-name</param-value>
也就是增加一个"targetbeanname"的参数,值为实际执行filter的bean。
注意:filter和servlet都可以对url进行处理,filter是一个链式处理,只要你想继续处理就可以传递下去;而servlet则是一次处理并返回!适合简单逻辑处理。
附录:
<url-pattern>可以选择以下几种形式
/* 所有资源
*.html 以html结尾的资源
/fold/* 指定目录
/abc.html 指定文件
以”/’开头和以”/*”结尾的是用来做路径映射的,
以前缀”*.”开头的是用来做扩展映射的。
为什么定义”/*.action”这样一个看起来很正常的匹配会错?
因为这个匹配即属于路径映射,也属于扩展映射,导致容器无法判断。
此外,filter就像"递归",在web.xml配置中的顺序代表了filter的调用流程,而servlet被调用后不会继续调用其他的servlet!因此配置中的顺序不影响!
小结:工作之后才知道,每天可以积累的东西很多,但的确没多少时间写出来!理解一个东西需要花点时间,但写出来就需要花更多的时间……写出来的好处就不用多说了,希望以后多挤一些时间,好好沉淀下。
(全文完)