来自文档:Struts2's Advanced Wildcard Mappings:
高级通配符
从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
请求,BookAction的字段“type
”将设置为“fiction
”,并且 字段“title
”将设置为“Frankenstein
”。
这绝对是好的,如果你在常规的Action方法中读取这些变量就可以正常工作,比如execute()
。
如果您尝试从prepare()
方法中读取它们,则它们为空,因为PrepareInterceptor
在其他负责设置参数的拦截器之前运行;解决此问题的常用方法是使用适当的拦截器堆栈来获取在执行prepare()
方法时已经填充的参数...
<!-- 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设置的参数。它们仍然是空的。
如何解决此问题?
答案 0 :(得分:4)
这些参数不是由ParametersInterceptor设置的(就像那些来自JSP的参数),而是StaticParametersInterceptor 的。要让它们填入prepare()
方法,必须应用paramsPrepareParamsStack
的相同技巧
由于没有拦截器堆栈可以执行开箱即用的,因此必须对其进行定义。
从defaultStack
开始,我们应该创建一个这样的堆栈:
<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,它完美无缺。
答案 1 :(得分:0)
@Andrea解决方案是很好的解决方案,但是我遇到了一些问题:
因此,我改用这个非常紧密的堆栈:
<interceptor-stack name="myOwnParamsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<!-- Needed for advanced wildcards parameters setted before prepare() -->
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params"/>
<!-- /Needed for advanced wildcards parameters setted before prepare() -->
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<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-stack>
顺便说一句,这是基于默认的paramsPrepareParamsStack和Andrea的答案。