Struts 2 Ajax Validation with jsonValidationWorkflowStack and Model Driven
Asked Answered
P

1

7

I'm trying to use Ajax validation in my Struts2 web app (with JQuery plugin) and i have an issue.

I had problems using the @Validations annotations so I'd just overrided the validate() method and all works fine with my xhtml forms now during the validation. The fieldsErrors are well recieved and printed in the gui.

The fact is, when the form is validated, a second POST is sent to the server to launch the Action. But, I don't know why, the framework doesn't set the model's attributes and during the generation of the HTML response after the execution of the Action, the framework can't access the attributes (only when I use the jsonValidationWorkflowStack).

I've created an simple example:

The Action

    @Namespace("/actions")
    @ParentPackage("actions")
    @InterceptorRef(value = "jsonValidationWorkflowStack")
   public class ActionTest extends ActionSupport implements
        ModelDriven<ModelTest>, ParameterAware {
    private static final long serialVersionUID = 1L;

    private ModelTest model;
    private Map<String, String[]> parameters;

    public ActionTest() {
        model = new ModelTest();
    }

    @Action(value = "actionTest", results = {
            @Result(name = SUCCESS, location = "/jsp/win.jsp"),
            @Result(name = ERROR, location = "/jsp/loose.jsp"),         
    })
    public String executeAction1() throws Exception {
        System.out.println("pass: "+getModel().getPass()); //the field is always null
        if ("test".equals(getModel().getPass()))
            return SUCCESS;
        return ERROR;
    }

    @Override
    public ModelTest getModel() {
        return model;
    }

    @Override
    public void validate() {
        String field;
        if (parameters.get("pass") != null) {
            field = parameters.get("pass")[0];
            if (field == null || field.isEmpty())
                addFieldError("pass", "the field is not set");
            else if (!"test".equals(field))
                addFieldError("pass", "the password is \"test\"");
        }

    }

    @Override
    public void setParameters(Map<String, String[]> arg0) {
        this.parameters = arg0;

    }
}

The Model

    public class ModelTest {

    private String pass;
    public String getPass() {
        return pass;
    }
    public void setPass(String pass) {
        this.pass = pass;
    }
}

The Form

<s:form action="actionTest" theme="xhtml">
<s:textfield name="pass"/>
<sj:submit validate="true"/>
</s:form>

In this example: - I'm always redirected to loose.jsp even if the password is "test" - If I want to print a in another jsp redirected by this action, i saw nothing (even if i set a default value in the model).

Can you give me a hand please???

PS: Sorry for my poor english :/

Prudie answered 24/9, 2012 at 13:25 Comment(2)
What will happen if you remove ParameterAware interface? Can you tell why do you use this interceptor? I am using the same usecase which you described and every thing works fine? You can validate your action via @valid too. It works fine with model properties.Bewley
The problem may be related to this: https://mcmap.net/q/1630111/-unexpected-exception-caught-setting-39-xxx-39-on-39-class-xxx-error-setting-expression-39-xxx-39-with-value-39-x-39Phthisic
K
0

Actually the model driven interceptor comes with the defaultStack

<interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="profiling"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo\..*</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>

and the jsonValidationWorkflowStack does not beacuse only includes basicStack

<interceptor-stack name="jsonValidationWorkflowStack">
                <interceptor-ref name="basicStack"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
                <interceptor-ref name="jsonValidation"/>
                <interceptor-ref name="workflow"/>
</interceptor-stack>

this is the basicStack

<interceptor-stack name="basicStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*,^struts\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
</interceptor-stack>

try adding

@Namespace("/actions")
    @ParentPackage("actions")
    @InterceptorRefs({
       @InterceptorRef("jsonValidationWorkflowStack"),
       @InterceptorRef("defaultStack")
})
Knurl answered 31/8, 2014 at 21:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.