在下面的操作类中,我使用参数拦截器。
@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: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting 'extraParam' on 'class actions.TestAction: Error setting expression 'extraParam' with value ['', ]
params.excludeParams
不排除参数extraParam
就像在 Action 类中一样。
我们能否在使用参数拦截器时以某种方式防止此类异常。此类消息不必要地添加到操作消息中并通过 <s:actionmessage/>
显示。 ,如果使用的话,当它们根本不应该显示时。
如果这个paramsPrepareParamsStack
替换为 defaultStack
然后在操作类中,不会出现此类消息。它只是给出如下警告。
WARNING: Parameter [extraParam] is on the excludeParams list of patterns!
请不要只是说,设置 struts.devMode
至false
禁用
此类消息。
最佳答案
我已经在评论中说过,如果您定义自己的一组参数来覆盖默认设置,则拦截器参数不会被父包的拦截器配置继承。请参阅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
名称时才有效。 > 在堆栈中。
如果您在 paramsPrepareParamsStack
中有两个 params
拦截器的引用,那么您无法覆盖第二个 params
interceptor- ref
除非您创建自己的拦截器堆栈并在拦截器的每个引用上指定参数覆盖。
关于jsp - 没有修改器和访问器(setters/getters)的参数以及 Struts 2 中的参数拦截器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21607121/