小编典典

在Prepare()方法中找不到高级通配符映射参数

java

从文档中:Struts2的高级通配符映射

高级通配符

从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方法(例如)读取这些变量,则效果很好execute()

如果尝试从prepare()方法中读取它们,则它们为null,因为PrepareInterceptor在其他Interceptor之前的运行负责设置参数。解决此问题的常用方法是在执行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. -->

这对于来自页面的参数非常有用,但 不适用于Advanced Wildcards设置的参数 。它们仍然为空。

如何解决这个问题?


阅读 285

收藏
2020-09-15

共1个答案

小编典典

该参数不是由ParametersInterceptor设置的(就像来自JSP的那些参数一样),而是

StaticParametersInterceptor设置的

为了将它们填充到prepare()方法中,paramsPrepareParamsStack必须使用相同的技巧。
由于没有 现成 的Interceptor Stack ,您必须对其进行定义。
从开始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,它可以完美地工作。

2020-09-15