Spring框架之Filter應用

在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>
    <filter-name>permissionFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

由filter和filter-mapping構成。filter指定過濾器處理類(實現了Filter接口),filter-mapping指定過濾的規則。

B:高級配置(允許代理注入Spring bean)

在web.xml中增加如下內容:

<filter>
    <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>
 <filter-mapping>
    <filter-name>permission</filter-name>
    <url-pattern>*.htm</url-pattern>
</filter-mapping>

在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。

(注意這個過濾器其實是一個DelegatingFilterProxy,這個過濾器裏沒有實現過濾器的任何邏輯。 DelegatingFilterProxy做的事情是代理Filter的方法,從application context裏獲得bean。 這讓bean可以獲得spring web application context的生命週期支持,使配置較爲輕便。 )

在Spring中配置的bean必須實現javax.servlet.Filter接口,它的name要和web.xml中的<filter-name>一樣。查看DelegatingFilterProxy的javadoc獲得更多信息。

此外,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的另外一種配置方式:

<filter>
    <filter-name>permission</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>Spring-bean-name</param-value>
    </init-param>
</filter>

也就是增加一個"targetBeanName"的參數,值爲實際執行Filter的bean。

注意Filter和servlet都可以對URL進行處理,Filter是一個鏈式處理,只要你想繼續處理就可以傳遞下去;而Servlet則是一次處理並返回!適合簡單邏輯處理。

附錄:
<url-pattern>可以選擇以下幾種形式

/*  所有資源
*.html  以html結尾的資源
/fold/* 指定目錄
/abc.html   指定文件
以”/’開頭和以”/*”結尾的是用來做路徑映射的,
以前綴”*.”開頭的是用來做擴展映射的。

爲什麼定義”/*.action”這樣一個看起來很正常的匹配會錯?
因爲這個匹配即屬於路徑映射,也屬於擴展映射,導致容器無法判斷。

此外,filter就像"遞歸",在web.xml配置中的順序代表了filter的調用流程,而servlet被調用後不會繼續調用其他的servlet!因此配置中的順序不影響!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章