2013-10-21 34 views
2

從文檔:Struts2's Advanced Wildcard Mappings高級通配符映射參數prepare()方法

高級通配符

從2.1.9+正則表達式可以定義在動作 名定義。要使用這種形式的外卡,下面的常量必須是 集:

<constant name="struts.enable.SlashesInActionNames" value="true"/> 
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/> 
<constant name="struts.patternMatcher" value="regex" /> 

正則表達式可以有兩種形式,最簡單的一種是 {FIELD_NAME},在這種情況下,與FIELD_NAME領域的 行動將與匹配的文本來填充,例如:

<package name="books" extends="struts-default" namespace="/"> 
    <action name="/{type}/content/{title}" class="example.BookAction"> 
     <result>/books/content.jsp</result> 
    </action> 
</package> 

在這個例子中,如果/fiction/content/Frankenstein是 請求的URL,BookAction的領域「type」將被設置爲「fiction「,並且 字段」title「將被設置爲」Frankenstein「。

這是絕對好的,並且如果您在普通的Action方法中讀取這些變量,例如​​,它就可以正常工作。

如果您嘗試從prepare()方法中讀取它們,則它們爲空,因爲PrepareInterceptor在負責設置參數的其他攔截器之前運行;解決這個問題的常用方法是使用貼切的攔截器棧得到執行prepare()方法時已經填充的參數...

從文檔:ParamsPrepareParamStack

<!-- An example of the paramsPrepareParams trick. This stack 
    is exactly the same as the defaultStack, except that it 
    includes one extra interceptor before the prepare interceptor: 
    the params interceptor. 

    This is useful for when you wish to apply parameters directly 
    to an object that you wish to load externally (such as a DAO 
    or database or service layer), but can't load that object 
    until at least the ID parameter has been loaded. By loading 
    the parameters twice, you can retrieve the object in the 
    prepare() method, allowing the second params interceptor to 
    apply the values on the object. --> 

這對於產生的參數的偉大工程從頁面,但它不適用於由高級通配符設置的參數。他們仍然是空的。

如何解決此問題?

回答

4

即參數不被ParametersInterceptor設置(如那些從JSP未來),但StaticParametersInterceptor
要讓他們填寫prepare()方法,必須應用paramsPrepareParamsStack的相同技巧。
由於沒有一個攔截器堆棧可以實現這一功能,所以您必須對其進行定義。
defaultStack開始,我們應該建立這樣一個Stack:

<interceptor-stack name="allYourParamsAreBelongToUsStack"> 
    <interceptor-ref name="exception"/> 
    <interceptor-ref name="alias"/> 
    <interceptor-ref name="servletConfig"/> 
    <interceptor-ref name="i18n"/> 
<!-- THE TRICK: NOW PREPARE() WILL FIND EVERYTHING SET -->  
    <interceptor-ref name="staticParams"/> 
    <interceptor-ref name="actionMappingParams"/> 
    <interceptor-ref name="params"> 
     <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> 
    </interceptor-ref> 
<!-- END OF THE TRICK --> 
    <interceptor-ref name="prepare"/> 
    <interceptor-ref name="chain"/> 
    <interceptor-ref name="scopedModelDriven"/> 
    <interceptor-ref name="modelDriven"/> 
    <interceptor-ref name="fileUpload"/> 
    <interceptor-ref name="checkbox"/> 
    <interceptor-ref name="multiselect"/> 
    <interceptor-ref name="staticParams"/> 
    <interceptor-ref name="actionMappingParams"/> 
    <interceptor-ref name="params"> 
     <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> 
    </interceptor-ref> 
    <interceptor-ref name="conversionError"/> 
    <interceptor-ref name="validation"> 
     <param name="excludeMethods">input,back,cancel,browse</param> 
    </interceptor-ref> 
    <interceptor-ref name="workflow"> 
     <param name="excludeMethods">input,back,cancel,browse</param> 
    </interceptor-ref> 
    <interceptor-ref name="debugging"/> 
</interceptor-stack> 

注:不需要ActionMappingParams,只是用於未來用途。

請注意以防萬一您發現任何與此相關的問題。 AFAIK,它完美無瑕。