没有mutators和访问器(setter/getters)的参数以及Struts 2中的参数拦截器

Tin*_*iny 7 jsp struts2 interceptor struts2-interceptors

在下面的动作类中,我使用的是参数拦截器.

@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 {}
}
Run Code Online (Sandbox Code Playgroud)

以下是<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>
Run Code Online (Sandbox Code Playgroud)

这里,隐藏的表单字段extraParam未声明,因此在操作类中没有setter和getter.

在这种情况下,提交此表单时,服务器终端上会显示以下消息.

严重:开发人员通知(将struts.devMode设置为false以禁用此消息):意外的异常捕获在'class actions.TestAction上设置'extraParam':错误设置表达式'extraParam',其值为['',]

params.excludeParams不排除extraParam动作类中的参数.

我们可以在使用参数拦截器时以某种方式防止此类异常.这些消息被不必要地添加到动作消息中,并且<s:actionmessage/>如果使用的话,当它们根本不应该被显示时显示.


如果在动作类中paramsPrepareParamsStack替换它defaultStack,则不会出现此类消息.它只是发出如下警告.

警告:参数[extraParam]位于excludeParams模式列表中!

请不要只是说,设定struts.devModefalse禁止此类消息.

Rom*_*n C 2

我已经在评论中说过,如果您定义自己的一组覆盖默认设置的参数,则拦截器参数不会被父包的拦截器配置继承。请参阅拦截器参数重写继承

还有一些技术用于获取拦截器参数的两个不同映射,请参阅在 Struts2 中获取拦截器参数

约定插件创建从某些父包继承的 XWork 包配置。请参阅我对Struts 2 Convention Plugin Define Multiple Parent Packages的回答。

因此,如果您想将自己的参数添加到集合中,您所要做的就是覆盖父配置设置的默认参数。无论是interceptor标签还是interceptor-stack标签,您都应该为每个interceptor-ref标签执行此操作。

约定插件使用@InterceprorRef注释来达到相同的目的,但需要注意的是,如果应用于类,它将应用于该类的每个操作。因此,在类级别使用此注释时要小心。您将覆盖拦截器堆栈参数,因此您应该为每个参数名称使用前缀,后跟堆栈中引用的拦截器名称的点,但这仅在interceptor-ref堆栈中具有唯一名称的情况下才有效。

如果您有两个params拦截器引用,那么paramsPrepareParamsStack您无法覆盖第二个引用params interceptor-ref,除非您创建自己的拦截器堆栈并在拦截器的每个引用上指定参数覆盖。