在下面的动作类中,我正在使用参数拦截器。
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "struts-default")
@InterceptorRefs(@InterceptorRef(value="store", params={"operationMode", "AUTOMATIC"}))
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, Preparable
{
private static final long serialVersionUID = 1L;
private String param1;
private String param2;
//Getters and setters.
public TestAction() {}
@Action(value = "TestMessage",
results = {
@Result(name=ActionSupport.SUCCESS, type="redirectAction", params={"namespace", "/admin_side", "actionName", "Test"}),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs={
@InterceptorRef(value="paramsPrepareParamsStack", params={"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true"})
})
public String insert() {
// Do something. Add or update a row to the database (one at a time).
addActionMessage("Action message");
addActionError("Error message");
return ActionSupport.SUCCESS;
}
@Action(value = "Test",
results = {
@Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs = {
@InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
public String load() throws Exception {
// This method is just required to return an initial view on page load.
return ActionSupport.SUCCESS;
}
@Override
public void prepare() throws Exception {}
}
以下是<s:form>
:
<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
<s:if test="hasActionMessages()">
<s:actionmessage theme="jquery"/>
</s:if>
<s:if test="hasActionErrors()">
<s:actionerror theme="jquery"/>
</s:if>
<s:hidden name="param1"/>
<s:hidden name="param2"/>
<s:hidden name="extraParam"/>
<s:submit value="Submit" action="TestMessage"/>
</s:form>
此处,隐藏的表单字段extraParam
未声明,因此在操作类中没有setter和getter。
在这种情况下,提交此表单时,服务器终端上会显示以下消息。
SEVERE:开发人员通知(将struts.devMode设置为false以禁用 此消息):Unexpected Exception捕获设置'extraParam' 'class actions.TestAction:错误设置表达式'extraParam' 值['',]
params.excludeParams
不排除动作类中的参数extraParam
。
我们可以在使用参数拦截器时以某种方式防止此类异常。此类消息不必要地添加到操作消息中,并在<s:actionmessage/>
显示时显示,如果使用的话,根本不应显示这些消息。
如果此动作类中的paramsPrepareParamsStack
被defaultStack
替换,则不会显示此类消息。它只是发出如下警告。
警告:参数[extraParam]位于excludeParams列表中 图案!
请不要只是说,将struts.devMode
设置为false
以禁用
这样的消息。
答案 0 :(得分:2)
我已经在评论中说过,如果您定义了一组覆盖默认设置的参数,拦截器参数不会被父包的拦截器配置继承。见Interceptor Parameter Overriding Inheritance。
还有一些技术用于获取两个不同的拦截器参数图,请参阅Getting Interceptor Parameters in Struts2。
约定插件创建从某个父包继承的XWork包配置。请参阅我对Struts 2 Convention Plugin Define Multiple Parent Packages的回答。
因此,如果要将自己的参数添加到集合中,您所要做的就是覆盖父配置设置的默认参数。 interceptor
代码或interceptor-stack
代码,您应该为每个interceptor-ref
代码执行此操作。
约定插件使用@InterceprorRef
注释用于相同的目的,但有一个警告,如果应用于类,它适用于该类的每个操作。因此,在类级别上使用此批注时要小心。您正在覆盖拦截器堆栈参数,因此您应该为每个参数名称使用堆栈中引用的拦截器名称的前缀后跟,但这仅在堆栈中具有interceptor-ref
的唯一名称时才有效。
如果params
中有paramsPrepareParamsStack
拦截器的两个引用,则除非您创建自己的拦截器堆栈,否则无法覆盖第二个params
interceptor-ref
并在拦截器的每个引用上指定参数覆盖。
答案 1 :(得分:1)
让我们看看paramsPrepareParamsStack
:
<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</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-stack>
有2个params
拦截器。当您在动作类中设置excludeParams
参数时,可能会为第一个params
拦截器设置此参数 - 第二个拦截器的参数保持默认值。现在,当调用第二个params
拦截器(默认为excludeParams
)时,抛出给定的异常。
您可以尝试复制excludeParams
参数的设置,以便为第二个拦截器设置它:
@InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
答案 2 :(得分:1)
我不是说完全,
示例代码如下:
<s:form action="save" method="post">
<s:textfield key="personBean.firstName" />
<s:textfield key="personBean.lastName" />
<s:textfield key="personBean.email" />
<s:textfield key="personBean.phoneNumber" />
<s:select key="personBean.sport" list="sports" />
<s:radio key="personBean.gender" list="genders" />
<s:select key="personBean.residency" list="states" listKey="stateAbbr" listValue="stateName"/>
<s:checkbox key="personBean.over21" />
<s:checkboxlist key="personBean.carModels" list="carModelsAvailable" />
<s:submit key="submit" />
</s:form>
也许它无法正常转到此链接: