在WebWork 2.2中,默認已經使用Filter的方式來進行對action的處理,這樣做固然帶來了很多好處,但是也有很多弊端.
當然,事情總是不斷進步的,我們就要揚長避短了.
使用Filter方式帶來的優點有:
- 可以服務靜態內容(當然后來webwork也提供了方式來避免服務靜態內容,因為對于普通文件應用服務器一般不比普通web服務器性能好)
- 可以處理多種請求,當然目前也沒有更多的請求處理
缺點有:
- 在Servlet 2.3中,不能使用jsp:include或者ww:include包含action輸出的結果了(當然可以使用ww:action)
- 一個請求如果發生了Forward,一般不會再經過Filter了(include同理,這是前面一條的原因)
- 由于Servlet和Filter的不同,還會有很多其他問題--不過目前還沒有注意到
首先我們來看看如何配置Filter
?
配置WebWork的Filter
在最簡單的情況下,webwork 2.2.的web.xml是這樣的:
??? <filter> ??????? <filter-name>webwork</filter-name> ??????? <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class> ??? </filter>
??? <filter-mapping> ??????? <filter-name>webwork</filter-name> ??????? <url-pattern>/*</url-pattern> ??? </filter-mapping>
|
如果使用了SiteMesh,那么是這樣配置的:
?<filter> ???? <filter-name>webwork-cleanup</filter-name> ???? <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class> ?</filter> ??? <filter> ??????? <filter-name>sitemesh</filter-name> ??????? <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> ??? </filter> ?<filter> ???? <filter-name>webwork</filter-name> ???? <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class> ?</filter> ?<filter-mapping> ???? <filter-name>webwork-cleanup</filter-name> ???? <url-pattern>/*</url-pattern> ?</filter-mapping> ?<filter-mapping> ???? <filter-name>sitemesh</filter-name> ???? <url-pattern>/*</url-pattern> ?</filter-mapping> ?<filter-mapping> ???? <filter-name>webwork</filter-name> ???? <url-pattern>/*</url-pattern> ?</filter-mapping>
|
注意中間是使用jsp時的配置,如果使用FreeMarker,要換成對應的PageFilter. (WebWork提供了FreeMarkerPageFilter和VelocityPageFilter)
?
分析Servlet 規范
Filter在Servlet 2.3規范中出現,配置方式就和最簡單的webwork的配置相同,在Servlet 2.4中,對mapping做了改進,可以設置Filter服務于何種請求.舉例如下:
??? <filter-mapping> ??????? <filter-name>webwork</filter-name> ??????? <url-pattern>/*</url-pattern> ??<dispatcher>FORWARD</dispatcher> ??<dispatcher>REQUEST</dispatcher> ??<dispatcher>INCLUDE</dispatcher> ??? </filter-mapping>
|
也就是說,Filter通過配置可以服務FORWARD和INCLUDE(以及ERROR)方式的請求了,而在Servlet 2.3中,是沒有規定的.而在Servlet 2.4中,如果沒有設置dispatcher,默認情況下是僅服務REQUEST類型的請求. 我覺得在Servlet 2.3的情況下,Filter也應該僅服務于REQUEST請求.(在Tomcat 下,本人測試確實如此,其他環境沒有測試)
通過上述分析,我們可以看到,如果應用服務器支持Servlet 2.4,通過設置我們的web.xml為2.4的格式,然后設置Filter的服務類型,則可以對FORWARD,INCLUDE,ERROR類型的請求進行服務.
通過Servlet 2.4規范我們可以避免一些使用Filter的缺點,當然如果設置不當,可能也會帶來一些毛病:
- 如果sitemesh映射處理不好,可能一個頁面被多次裝飾,所以要注意裝飾設置和Filter設置的合理搭配
- 多次經過Filter,可能會造成混亂,以及性能問題
Include 一個Action
前面我們說過,升級到webwork 2.2后,文檔上已經說使用ww:action的調用來替換ww:include和jsp:include對一個action的包含,當然我也是推薦ww:action來替換老的方式的. 但是這不等于說ww:include,jsp:include不能包含一個action了.
通過對filter-mapping的dispatcher的設置,可以完全使用包含action.
?<filter-mapping> ???? <filter-name>webwork</filter-name> ???? <url-pattern>/*</url-pattern> ??????? <dispatcher>REQUEST</dispatcher> ??????? <dispatcher>FORWARD</dispatcher> ??????? <dispatcher>INCLUDE</dispatcher> ?</filter-mapping>
|
注意如果有其他相關的Filter,也要進行類似配置,例如webwork-cleanup.
警告:我們不推薦使用這種方式!
URL Rewrite Filter的使用
url rewrite filter是一個java編寫的優秀的重寫url引擎.用于在java應用中重寫URL. 當然如果你有web服務器的重寫權限(例如apache),最好使用web服務器的ReWrite引擎,它們的效率會高于Url Rewrite Filter.
在WebWork 2.1.7的時候,因為WebWork使用Servlet處理請求,所以不對Filter造成不良影響,在WebWork 2.1.7中使用的配置如下:
??? <filter> ??????? <filter-name>UrlRewriteFilter</filter-name> ??????? <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> ??????? <init-param> ??????????? <param-name>logLevel</param-name> ??????????? <param-value>WARN</param-value> ??????? </init-param> ??? </filter> ??? <filter> ??????? <filter-name>sitemesh</filter-name> ??????? <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> ??? </filter> ??? <filter-mapping> ??????? <filter-name>UrlRewriteFilter</filter-name> ??????? <url-pattern>/someurl/*</url-pattern> ??? </filter-mapping>
??? <filter-mapping> ??????? <filter-name>sitemesh</filter-name> ??????? <url-pattern>/*</url-pattern> ??? </filter-mapping> ?<servlet> ??<servlet-name>webwork</servlet-name> ??<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class> ?</servlet> ? ?<servlet-mapping> ??<servlet-name>webwork</servlet-name> ??<url-pattern>*.action</url-pattern> ?</servlet-mapping>
|
而升級到webwork 2.2.2中時,由于webwork的配置改變了,對webwork的action的forward方式的重寫就會無法生效了.? ---如果你的rewrite全部都是redirect,則無須修改
(如果使用了forward重寫方式,會發生404錯誤)
在Servlet 2.3規范的應用服務器中,這可能是個無法解決的問題!(也許能通過修改某些程序的代碼可以做到)
如果你的應用服務器支持Servlet 2.4,則可以按照上面的說明修改web.xml,就可以繼續使用了. (但是要避免前面說的多次filter的問題)
配置示例如下:
<web-app version="2.4" ?xmlns="http://java.sun.com/xml/ns/j2ee" ?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ?xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee ?http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> ??? <filter> ??????? <filter-name>UrlRewriteFilter</filter-name> ??????? <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> ??????? <init-param> ??????????? <param-name>logLevel</param-name> ??????????? <param-value>WARN</param-value> ??????? </init-param> ??? </filter> ?<filter> ???? <filter-name>webwork-cleanup</filter-name> ???? <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class> ?</filter> ??? <filter> ??????? <filter-name>sitemesh</filter-name> ??????? <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> ??? </filter> ?<filter> ???? <filter-name>webwork</filter-name> ???? <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class> ?</filter> ??? <filter-mapping> ??????? <filter-name>UrlRewriteFilter</filter-name> ??????? <url-pattern>/srun/*</url-pattern> ??????? <dispatcher>REQUEST</dispatcher> ??????? <dispatcher>FORWARD</dispatcher> ??? </filter-mapping> ?<filter-mapping> ???? <filter-name>webwork-cleanup</filter-name> ???? <url-pattern>/*</url-pattern> ??????? <dispatcher>REQUEST</dispatcher> ??????? <dispatcher>FORWARD</dispatcher> ?</filter-mapping> ?<filter-mapping> ???? <filter-name>sitemesh</filter-name> ???? <url-pattern>/*</url-pattern> ?</filter-mapping> ?<filter-mapping> ???? <filter-name>webwork</filter-name> ???? <url-pattern>/*</url-pattern> ??????? <dispatcher>REQUEST</dispatcher> ??????? <dispatcher>FORWARD</dispatcher> ?</filter-mapping>
|
注意sitemesh的filter的配置,你的可能和此處不同,因為我要避免頁面多次被裝飾.當然可以通過sitemesh的配置文件,設置只裝飾某個處理中的url即可. 也就是說,某種情況下,有可能你的sitemesh的filter-mapping中也要包括dispatcher的配置.
總之,要根據實際情況編寫自己的web.xml.
?
沒有好好組織,說的比較亂,請多見諒.
_____________________________________________
JavaScud 免費開源平臺 http://www.javascud.org