Curtis Snowden
Curtis Snowden

Reputation: 463

Struts2 Bootstrap Plugin Client Validation with File

I'm using the Struts2-Bootstrap-Plugin version 2.0.4 for the Client Validation. I'm using the bootstrapValidation as my validate function, and I've added the jsonValidationWorkflowStack to my struts actions. For most things, this works as expected, sending my form data to the server and executing my server validation without ever actually performing a full post. However, it's not working for files. If I have an s:file on the page, that seems to be ignored. It's always null when the validation method executes. If I bypass the plugin's client validation, the files submit correctly and are validated. What am I missing for the files to work? Thanks.

My Struts.xml

    <action name="testValidateSave" class="webapp.action.TestValidationAction" method="save" >
        <interceptor-ref name="jsonValidationWorkflowStack"/>

        <result name="success">/WEB-INF/pages/testValidate.jsp</result>
        <result name="error">/WEB-INF/pages/testValidate.jsp</result>
        <result name="input">/WEB-INF/pages/testValidate.jsp</result>
    </action>

My JSP page

<s:form id="testValidationForm" theme="bootstrap" method="post" labelCssClass="col-sm-2 text-semibold" elementCssClass="col-sm-10"
    cssClass="form-horizontal" action="testValidateSave" enctype="multipart/form-data">
<div class="panel panel-flat">
    <div class="panel-heading">
        <h5 class="panel-title text-bold">Testing Client Validation</h5>
        <div class="heading-elements">

            <sj:submit button="true"
                       name = "Save"
                       type="button"
                       id="saveButton"
                       formIds="testValidationForm"
                       targets="bodySection"
                       iframe="true"
                       dataType="html"
                       validate="true"
                       validateFunction="bootstrapValidation"
                       cssClass="btn bg-cobalt-400 mr-5 pull-right"
                       buttonIcon="icon-floppy-disk"
                       label="Save"
                       value="Save"
                       />
        </div>
    </div>
    <div id="bodySection" class="panel-body">

        <s:textfield
            id="testText"
            name="testText"
            label="Test Text"
            />

        <s:file
            id="testDoc"
            label="Test Doc"
            name="testDoc"/>

    </div>
</div>
</s:form>

And my action class:

public class TestValidationAction extends ActionSupport {
private static final long serialVersionUID = 1L;

private String testText;

private File testDoc;
private String testDocContentType;
private String testDocFileName;

/*****************************************************************
 * Action Methods
 *****************************************************************/

@SkipValidation
public String execute() {
    return SUCCESS;
}

public String save() {
    return SUCCESS;
}

public void validate() {
    super.validate();

    System.out.println("    testText = " + this.testText);
    System.out.println("    testDoc = " + this.testDoc );

    if (this.testText == null || this.testText.isEmpty()) {
        addFieldError("testText", "Required");
    }

    if (this.testDoc == null) {
        addFieldError("testDoc", "Required");
    }
}

/*****************************************************************
 * Getters and Setters
 *****************************************************************/

public String getTestText() {
    return this.testText;
}
public void setTestText(String testText) {
    this.testText = testText;
}

public File getTestDoc() {
    return this.testDoc;
}
public void setTestDoc(File testDoc) {
    this.testDoc= testDoc;
}

public String getTestDocFileName() {
    return this.testDocFileName;
}
public void setTestDocFileName(String testDocFileName) {
    this.testDocFileName= testDocFileName;
}

public String getTestDocContentType() {
    return this.testDocContentType;
}
public void setTestDocContentType(String testDocContentType) {
    this.testDocContentType= testDocContentType;
}
}

Upvotes: 0

Views: 402

Answers (1)

Curtis Snowden
Curtis Snowden

Reputation: 463

Got it figured out. I was missing the fileUpload interceptor. Of course, that wasn't enough, since only the first interceptor in an action is used, which I didn't realize at first. Had to combine everything into a new interceptor stack in the package and then assign that to the action.

Changes to the struts.xml that fixed the problem:

<package name="testPackage" extends="default,json-default" namespace="/testPackage">
    <interceptors>
        <interceptor-stack name="completeValidation">
            <interceptor-ref name="fileUpload"/>
            <interceptor-ref name="jsonValidationWorkflowStack"/>
        </interceptor-stack>
    </interceptors>
    
    <action name="testValidate" class="webapp.action.TestValidationAction">
        <result name="success">/WEB-INF/pages/testValidate.jsp</result>
    </action>
    <action name="testValidateSave" class="webapp.action.TestValidationAction" method="save" >
        <interceptor-ref name="completeValidation"/>
        
        <result name="success">/WEB-INF/pages/testValidate.jsp</result>
        <result name="error">/WEB-INF/pages/testValidate.jsp</result>
        <result name="input">/WEB-INF/pages/testValidate.jsp</result>
    </action>
</package

Everything functions correctly now.

Upvotes: 0

Related Questions