【问题标题】:Struts 2 Validation not working with dynamic form fieldsStruts 2 验证不适用于动态表单字段
【发布时间】:2016-08-21 06:10:23
【问题描述】:

我正在开发一个用户可以输入多个地址的应用程序。我正在使用 Struts2 XML 验证,对于这些字段 [地址(国家、城市、街道)],我使用了访问者验证器,但它不起作用。 其余字段的验证工作正常。

谁能提出可能是什么问题?

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>

【问题讨论】:

  • 您真的有访客验证器的验证文件吗? “访问者”的意思是“对于这个特定的字段,你会在另一个 XML 文件中找到验证规则,该文件位于模型文件夹中,而不是在操作文件夹中”.
  • 我收到了错误。请通过添加访问者验证器文件名、包和代码以及 AddressModel 代码来更新您的问题,以便我可以更完整的方式回答
  • 先生,我已编辑。请检查。 EmployeeModel-Validation.xml 与模型类一起保存,EmployeeAction-Validation.xml 与 Action 类一起保存在单独的包中。我也关注了你的博客。

标签: java validation jsp struts2 visitor-pattern


【解决方案1】:

你有一个 EmployeeModel 对象,它有多个 AddressModel 对象。

这意味着在 Action 验证文件中,您需要对 EmployeeModel 属性使用 simple 验证,对 AddressModel 对象使用 visitor 验证。

您说得对,AddressModel 必须通过此处的访问者验证进行验证:

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

但是,您尝试使用EmployeeModel 的验证文件,而不是AddressModel 的验证文件!

代替

EmployeeModel-Validation.xml

你需要使用

AddressModel-Validation.xml

在其中,您需要验证简单的属性,它们前面没有任何employeeModel(因为此验证可能被许多不同的验证文件访问者使用,具有包含AddressModel 的不同操作和模型,即不关心它的父对象):

<!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>

编辑:

您还忘记命名AddressModel 对象的属性;添加它们:

<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>

并在您的 javascript 代码中执行相同的操作。

【讨论】:

  • 先生,我已经更新了字段名称,仍然没有成功:(现在可能是什么问题?
  • 我很确定它是模型驱动的......你甚至没有在你的页面中使用它:) 只需删除它,它只会造成麻烦并增加不必要的复杂性。还将地址的定义和设置器从 ArrayList 更改为接口 List
  • 不,HTML 字段非常好。我看到 XML 验证文件中大写的 V 是错误的,它应该是小写的(但我不知道它是否会阻止验证工作)。也就是说,您的 VO 中是否有带有参数的构造函数,但您没有在此处发布?如果是,也添加一个无参数构造函数。然后在这里发布您的 struts.xml 配置(拦截器堆栈和操作配置)
  • 一定有什么非常奇怪的事情发生了:|如果您确认文件AddressModel-validation.xmlcom.model 包中。请注意,您必须在所有 VO 上实现 Serializable(EmployeeModel 和 AddressModel),但如果这是罪魁祸首,我会感到惊讶。做最后一次更新,如果它不起作用,把你修改过的代码转储到原来的地方(除了作为问答主题的 XML 验证文件,应该添加到你的问题中,而不是替换原来的的)。
  • 它们没有显示,因为您使用的是 html 标签而不是 struts 标签(页面加载时只有第一行可用)。在表单顶部放置一个 标签,它们就会被绘制出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多