在以下动作类中,我使用了参数拦截器。
@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>
<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未声明,因此在动作类中没有设置方法和获取方法。
extraParam
在这种情况下,提交此表单后,以下消息将出现在服务器终端上。
严重:开发人员通知(将struts.devMode设置为false以禁用此消息):意外的异常在“类动作”上设置了“ extraParam”。TestAction:将表达式“ extraParam”设置为值[“,]时出错
params.excludeParams不像extraParam在动作类中那样排除参数。
params.excludeParams
我们可以在使用参数拦截器时以某种方式防止此类异常吗?<s:actionmessage/>如果根本不显示此类消息,则将它们不必要地添加到操作消息中并通过(如果使用)显示。
<s:actionmessage/>
如果在操作类中将其paramsPrepareParamsStack替换为defaultStack,则不会出现此类消息。它仅给出如下警告。
paramsPrepareParamsStack
defaultStack
警告:参数[extraParam]在模式的excludeParams列表上!
请不要只是说, 设定struts.devMode到false到禁止此类消息。
struts.devMode
false
我已经在评论中说过,如果您定义自己的参数集来覆盖默认设置,则拦截器参数不会被父程序包的拦截器配置继承。请参见拦截器参数重写继承。
还有一些用于获取拦截器参数的两个不同映射的技术,请参阅在Struts2中获取拦截器参数。
约定插件创建从某些父包继承的XWork包配置。请参阅我对Struts 2 Convention Plugin定义多个父包的回答。
因此,如果要向集合添加自己的参数,您要做的就是覆盖父配置的默认参数集。无论是interceptor标签或interceptor- stack标签,你应该为每个做interceptor-ref标记。
interceptor
interceptor- stack
interceptor-ref
Conventional插件@InterceprorRef出于相同的目的使用注释,但要注意的是,如果将注释应用于类,它将应用于该类的每个动作。因此,在类级别使用此注释时要小心。您将覆盖拦截器堆栈参数,因此对于每个参数名称,都应在堆栈中引用拦截器名称的前缀后加点号,但这仅interceptor- ref在堆栈中具有唯一的s 时才有效。
@InterceprorRef
interceptor- ref
如果您在中有两个params拦截器的引用,paramsPrepareParamsStack那么params interceptor- ref除非您创建自己的拦截器堆栈并在拦截器的每个引用上指定参数覆盖,否则您将无法覆盖第二个引用。
params