简体   繁体   中英

Struts 2 Validation not working with dynamic form fields

I am working on an application where a user can enter multiple addresses. I am using Struts2 XML validation and for those fields [Address (Country, City, Street)], I have used visitor validator but it is not working. The validation is working fine on remaining fields.

Can anyone suggest what might be the problem ?

EmployeeForm.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//Dtd HTML 4.01 Transitional//EN" 
                      "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Add Employee</title>

<script language="javascript">
    function addRow(tableID) {

        var table = document.getElementById(tableID);

        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
        var counts=rowCount-1;
        var cell1 = row.insertCell(0);
        var street = document.createElement("input");
        street.type = "text";
        street.name="employeeModel.addresses["+counts+"].street";
        cell1.appendChild(houseNum);

        var cell2 = row.insertCell(1);
        var city = document.createElement("input");
        city.type = "text";
        city.name="employeeModel.addresses["+counts+"].city";
        cell2.appendChild(city);

        var cell3 = row.insertCell(2);
        var country = document.createElement("input");
        country.type = "text";
        country.name="employeeModel.addresses["+counts+"].country";
        cell3.appendChild(country);

    }
</script>

</head>
<body>
<s:form action="addEmployee.action" method="post" >
    <s:textfield label="Name" name="employeeModel.employeeName" size="20" />

    <table id="addressesTable" width="350px" border="1">
    <tr>
        <td>Street</td>
        <td>City</td>
        <td>Country</td>
    </tr>
    <tr>
        <td><input type="text" name="employeeModel.addresses[0].street" /></td>    
        <td><input type="text" name="employeeModel.addresses[0].city" /></td>
        <td><input type="text" name="employeeModel.addresses[0].country" /></td>
    </tr>
    </table>
    <input type="button" value="Add More" onclick="addRow('addressesTable')" />
    <s:submit />

</s:form>
</body>
</html>

EmployeeAction-Validation.xml

<validators>
<field name="employeeModel.employeeName">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>Name is required.</message>
        </field-validator>
    </field>
<field name="employeeModel.addresses" >
      <field-validator type="visitor">
          <message></message>
      </field-validator>
    </field>
</validators>

EmployeeModel-Validation.xml

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
  <field name="employeeModel.addresses" >
      <field-validator type="visitor">
          <message></message>
      </field-validator>
  </field>
</validators>

EmployeeAction.java

 package com.action;

import com.model.EmployeeModel;
import com.opensymphony.xwork2.ActionSupport;

public class EmployeeAction extends ActionSupport{

    private static final long serialVersionUID = 1L;
    private EmployeeModel employeeModel;

    public String execute() {
        return SUCCESS;
    }


    public EmployeeModel getEmployeeModel() {
        return employeeModel;
    }

    public void setEmployeeModel(EmployeeModel employeeModel) {
        this.employeeModel = employeeModel;
    }
}

EmployeeModel.java

 package com.model;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class EmployeeModel implements Serializable{

    private static final long serialVersionUID = -484846216250373240L;
    private String employeeName;
    private List<AddressModel> addresses;

    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public List<AddressModel> getAddresses() {
        return addresses;
    }
    public void setAddresses(List<AddressModel> addresses) {
        this.addresses = addresses;
    }
}

AddressModel.java

 package com.model;

import java.io.Serializable;

public class AddressModel implements Serializable{

    private static final long serialVersionUID = 6965346469594926268L;
    private String country;
    private String city;
    private String street;

    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }   
}

struts.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <package name="default" extends="struts-default">
      <action name="addEmployee" class="com.action.EmployeeAction" >
            <result name="success">/Result.jsp</result>
            <result name="input">/EmployeeForm.jsp</result>
      </action>
   </package>
</struts>

You have one EmployeeModel object, that has multiple AddressModel objects.

This means that in the Action validation file, you need to use simple validation for EmployeeModel properties, and visitor validation for AddressModel object.

You are correctly saying that AddressModel must be validated through visitor validation here:

<field name="employeeModel.addresses" >
    <field-validator type="visitor">

but then, instead of the validation file for AddressModel , you are trying to use a validation file for EmployeeModel !

Instead of

EmployeeModel-Validation.xml

you need to use

AddressModel-Validation.xml

and inside it, you need to validate the simple properties, without any employeeModel in front of them (because this validation could be visitor-used by many different validation files, with different actions and models containing AddressModel , that doesn't care about its parent objects):

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
    <field name="country">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>Country is required.</message>
        </field-validator>
    </field>
</validators>

EDIT:

You've also forgot to name the attributes of your AddressModel object; add them:

<td><input type="text" name="employeeModel.addresses[0].street" /></td>
<td><input type="text" name="employeeModel.addresses[0].city"    /></td>
<td><input type="text" name="employeeModel.addresses[0].country"  /></td>

and do the same in your javascript code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM