@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未声明,因此在action类中没有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不会在action类中排除参数extraParam.
我们可以在使用参数拦截器时以某种方式防止此类异常.这些消息被不必要地添加到动作消息中并通过< s:actionmessage />显示(如果使用的话),当它们根本不应该被显示时.
如果此动作类中的paramsPrepareParamsStack被defaultStack替换,则不会出现此类消息.它只是发出如下警告.
WARNING: Parameter [extraParam] is on the excludeParams list of
patterns!
请不要只说,将struts.devMode设置为false以禁用
这样的消息.
还有一些技术用于获得两个不同的拦截器参数图,见Getting Interceptor Parameters in Struts2.
约定插件创建从某个父包继承的XWork包配置.请参阅我的答案Struts 2 Convention Plugin Define Multiple Parent Packages.
因此,如果要将自己的参数添加到集合中,您所要做的就是覆盖父配置设置的默认参数.拦截器标签或拦截器堆栈标签,您应该为每个interceptor-ref标签执行此操作.
约定插件使用@InterceprorRef
注释用于相同的目的,但有一个警告,如果应用于类,它适用于该类的每个操作.因此,在类级别上使用此批注时要小心.您正在覆盖拦截器堆栈参数,因此您应该使用前缀后跟每个参数名称的堆栈中引用的拦截器名称的点,但这仅在堆栈中具有interceptor-refs的唯一名称时才有效.
如果你在paramsPrepareParamsStack中有两个params拦截器的引用,那么你不能覆盖第二个params interceptor-ref,除非你创建自己的拦截器堆栈并在拦截器的每个引用上指定参数覆盖.