在WebWork 2.2中,默認(rèn)已經(jīng)使用Filter的方式來進(jìn)行對(duì)action的處理,這樣做固然帶來了很多好處,但是也有很多弊端.
當(dāng)然,事情總是不斷進(jìn)步的,我們就要揚(yáng)長(zhǎng)避短了.
使用Filter方式帶來的優(yōu)點(diǎn)有:
- 可以服務(wù)靜態(tài)內(nèi)容(當(dāng)然后來webwork也提供了方式來避免服務(wù)靜態(tài)內(nèi)容,因?yàn)閷?duì)于普通文件應(yīng)用服務(wù)器一般不比普通web服務(wù)器性能好)
- 可以處理多種請(qǐng)求,當(dāng)然目前也沒有更多的請(qǐng)求處理
缺點(diǎn)有:
- 在Servlet 2.3中,不能使用jsp:include或者ww:include包含action輸出的結(jié)果了(當(dāng)然可以使用ww:action)
- 一個(gè)請(qǐng)求如果發(fā)生了Forward,一般不會(huì)再經(jīng)過Filter了(include同理,這是前面一條的原因)
- 由于Servlet和Filter的不同,還會(huì)有很多其他問題--不過目前還沒有注意到
首先我們來看看如何配置Filter
?
配置WebWork的Filter
在最簡(jiǎn)單的情況下,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時(shí)的配置,如果使用FreeMarker,要換成對(duì)應(yīng)的PageFilter. (WebWork提供了FreeMarkerPageFilter和VelocityPageFilter)
?
分析Servlet 規(guī)范
Filter在Servlet 2.3規(guī)范中出現(xiàn),配置方式就和最簡(jiǎn)單的webwork的配置相同,在Servlet 2.4中,對(duì)mapping做了改進(jìn),可以設(shè)置Filter服務(wù)于何種請(qǐng)求.舉例如下:
??? <filter-mapping> ??????? <filter-name>webwork</filter-name> ??????? <url-pattern>/*</url-pattern> ??<dispatcher>FORWARD</dispatcher> ??<dispatcher>REQUEST</dispatcher> ??<dispatcher>INCLUDE</dispatcher> ??? </filter-mapping>
|
也就是說,Filter通過配置可以服務(wù)FORWARD和INCLUDE(以及ERROR)方式的請(qǐng)求了,而在Servlet 2.3中,是沒有規(guī)定的.而在Servlet 2.4中,如果沒有設(shè)置dispatcher,默認(rèn)情況下是僅服務(wù)REQUEST類型的請(qǐng)求. 我覺得在Servlet 2.3的情況下,Filter也應(yīng)該僅服務(wù)于REQUEST請(qǐng)求.(在Tomcat 下,本人測(cè)試確實(shí)如此,其他環(huán)境沒有測(cè)試)
通過上述分析,我們可以看到,如果應(yīng)用服務(wù)器支持Servlet 2.4,通過設(shè)置我們的web.xml為2.4的格式,然后設(shè)置Filter的服務(wù)類型,則可以對(duì)FORWARD,INCLUDE,ERROR類型的請(qǐng)求進(jìn)行服務(wù).
通過Servlet 2.4規(guī)范我們可以避免一些使用Filter的缺點(diǎn),當(dāng)然如果設(shè)置不當(dāng),可能也會(huì)帶來一些毛病:
- 如果sitemesh映射處理不好,可能一個(gè)頁面被多次裝飾,所以要注意裝飾設(shè)置和Filter設(shè)置的合理搭配
- 多次經(jīng)過Filter,可能會(huì)造成混亂,以及性能問題
Include 一個(gè)Action
前面我們說過,升級(jí)到webwork 2.2后,文檔上已經(jīng)說使用ww:action的調(diào)用來替換ww:include和jsp:include對(duì)一個(gè)action的包含,當(dāng)然我也是推薦ww:action來替換老的方式的. 但是這不等于說ww:include,jsp:include不能包含一個(gè)action了.
通過對(duì)filter-mapping的dispatcher的設(shè)置,可以完全使用包含action.
?<filter-mapping> ???? <filter-name>webwork</filter-name> ???? <url-pattern>/*</url-pattern> ??????? <dispatcher>REQUEST</dispatcher> ??????? <dispatcher>FORWARD</dispatcher> ??????? <dispatcher>INCLUDE</dispatcher> ?</filter-mapping>
|
注意如果有其他相關(guān)的Filter,也要進(jìn)行類似配置,例如webwork-cleanup.
警告:我們不推薦使用這種方式!
URL Rewrite Filter的使用
url rewrite filter是一個(gè)java編寫的優(yōu)秀的重寫url引擎.用于在java應(yīng)用中重寫URL. 當(dāng)然如果你有web服務(wù)器的重寫權(quán)限(例如apache),最好使用web服務(wù)器的ReWrite引擎,它們的效率會(huì)高于Url Rewrite Filter.
在WebWork 2.1.7的時(shí)候,因?yàn)閃ebWork使用Servlet處理請(qǐng)求,所以不對(duì)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>
|
而升級(jí)到webwork 2.2.2中時(shí),由于webwork的配置改變了,對(duì)webwork的action的forward方式的重寫就會(huì)無法生效了.? ---如果你的rewrite全部都是redirect,則無須修改
(如果使用了forward重寫方式,會(huì)發(fā)生404錯(cuò)誤)
在Servlet 2.3規(guī)范的應(yīng)用服務(wù)器中,這可能是個(gè)無法解決的問題!(也許能通過修改某些程序的代碼可以做到)
如果你的應(yīng)用服務(wù)器支持Servlet 2.4,則可以按照上面的說明修改web.xml,就可以繼續(xù)使用了. (但是要避免前面說的多次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的配置,你的可能和此處不同,因?yàn)槲乙苊忭撁娑啻伪谎b飾.當(dāng)然可以通過sitemesh的配置文件,設(shè)置只裝飾某個(gè)處理中的url即可. 也就是說,某種情況下,有可能你的sitemesh的filter-mapping中也要包括dispatcher的配置.
總之,要根據(jù)實(shí)際情況編寫自己的web.xml.
?
沒有好好組織,說的比較亂,請(qǐng)多見諒.
_____________________________________________
JavaScud 免費(fèi)開源平臺(tái) http://www.javascud.org