WebWork 2.2 Filter,Url Rewrite,Servlet規範

maqianmaqian發表於2010-09-09

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

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/bndxgae/archive/2006/07/10/899497.aspx

相關文章