Spring MVC将嵌套的Custom类型列表绑定到多个JSP表单


问题内容

案例: 我有一个组织对象。它有一个部门对象列表,每个部门都有一个雇员对象列表。

在JSP中,我有一个复选框列表,该复选框将复选框绑定到雇员对象(向下2个层次结构。即Organization-> Department->
Employee)。

<input type="checkbox" name="adminDepartmentList[${status.index}].employeeList" value="${employee.firstName}"> <c:out value="${employee.firstName}" /><br>

如你看到的:

adminDepartmentList[0].employeeList --> John
adminDepartmentList[2].employeeList --> Rose

绑定是好的。提交表单后,在控制器中,我可以遍历admin departmentList,找到所有创建的部门,并找到由于复选框选择而创建的员工。

问题:(
部门是用空名称创建的,而employeeList是非空的。我找不到employeeList所属部门的名称:(因此,如何传递某些部门名称,以便将该名称注入部门(如就像正在将“
.employeeList”注入部门一样。

详细信息: 为您提供我工作的详细信息:

一个组织类有两个部门列表。部门类具有员工列表。员工具有名字和姓氏以及hourToWork。

public class Organization{
  private long id;
  private String name;
  private List<Department> adminDepartmentList;   //n admin departments
  private List<Department> employeeDepartmentList //m employee departments
// default constructor and all getters and setters
}

public class Department{
  private long id;
  private String name;
  private List<Employee> employeeList; //k employees
  //default constructor and all getters and setters
}

public class Employee{
  private long id;
  private String firstName;
  private String lastName;
  private int hoursToWork;  // to be filled from Spring MVC form
  //default contructor and all getters and setters
}

部门列表来自API。该部门的所有员工都来自另一个API。

我正在编写一个客户端,该客户端使用户可以通过以下方式创建“定制组织”:首先选择他们感兴趣的部门,然后针对所选的每个部门,用户从与该部门相关的所有员工中选择一部分员工。

所以我有3种JSP形式:

组织形式(organization.jsp):组织名称的输入字段和所有部门的复选框列表。用户可以为正在创建的新组织选择一组部门。

<form:form name='fs' action="department.htm"  method='POST' commandName="organization">
            Organization Name:
            <input type="text" name="name" >
            <!-- ============================================================== -->
            Departments:<br> Select admin-departments you want.
            <div class="checkbox-list">
            <%-- Size :<c:out value="${organization.adminDepartmentList.size}"/> --%>
                <c:forEach var="i" varStatus="status" items="${organization.adminDepartmentList}">
              <input type="checkbox" name="adminDepartmentList" value="${i.name}"> <c:out value="${i.name}" /><br>
                  </c:forEach>
            </div>
            <!-- ============================================================== -->
            Departments:<br> Select employee-departments you want.
            <div class="checkbox-list">
                <c:forEach var="i" varStatus="status" items="${organization.employeeDepartmentList}">            
                      <input type="checkbox" name="employeeDepartmentList" value="${i.name}"> <c:out value="${i.name}" /><br>
                  </c:forEach>
            </div>
            <button type="submit" class="btn btn-lg btn-primary btn-block">Next Step</button>
  </form:form>

部门表单(department.jsp):对于所选的每个部门,这将显示要为该部门选择的员工的复选框列表。

<form:form name='f' action="employee.htm"  method='POST' commandName="organization">
            Organization Name: <c:out value="${organization.name}" /><br>
            Select Employees you want for your new Departments.
            Admin Departments:<br>
                <c:forEach var="department" varStatus="status" items="${organization.adminDepartmentList}">
                ______Dept: <c:out value="${department.name}" /><br>
                <div class="checkbox-list">
                    <c:forEach var="employee" varStatus="status" items="${department.employeeList}">
                          <input type="checkbox" name="adminDepartmentList[${status.index}].employeeList" value="${employee.firstName}"> <c:out value="${employee.firstName}" /><br>
                    </c:forEach>
                </div>
                </c:forEach>

              Employee Departments:<br>
                <c:forEach var="department" varStatus="status" items="${organization.employeeDepartmentList}">
                ______Dept: <c:out value="${department.name}" /><br>
                <div class="checkbox-list">
                    <c:forEach var="employee" varStatus="status" items="${department.employeeList}">
                          <input type="checkbox" name="employeeDepartmentList[${status.index}].employeeList" value="${employee.firstName}"> <c:out value="${employee.firstName}" /><br>
                    </c:forEach>
                </div>
                </c:forEach>

                  <button type="submit" class="btn btn-lg btn-primary btn-block">Next Step</button>
  </form:form>

员工表单(employee.jsp):对于在“部门表单”中选择的每个员工,这将显示员工姓名和一个字段,用于输入将分配给该员工的小时数。

员工控制者(部门名称为空的人)

@RequestMapping(value = "/employee", method = RequestMethod.POST)
  public String product_post(@ModelAttribute("organization") Organization organization, HttpServletRequest request,
            HttpServletResponse response, BindingResult result, ModelMap model) {
      System.out.println("=========== POST Employee CONTROLLER===============");
      //STEP 1. show me which employees are selected for each admin department.
      List<Department> adminDepartments = organization.getAdminDepartmentList();

      for(Department dept: adminDepartments){
        System.out.println("Admin Dept name::: " + dept.getName());  //<-----------Name Comes as null :(
        List<Employee> employeeList = dept.getEmployeeList();
        for(Employee emp: employeeList){
          System.out.println("Employee::"+ emp.getFirstName());
        }
      }

      //STEP 2. show me which employees are selected for each employee department.
      List<Department> employeeDepartments = organization.getEmployeeDepartmentList();
      for(Department dept: employeeDepartments){
        System.out.println("Employee Dept name::: " + dept.getName()); //<----------Name Comes as null :(
        List<Employee> employeeList = dept.getEmployeeList();
        for(Employee emp: employeeList){
          System.out.println("Employee::"+ emp.getFirstName());
        }
      }
      model.addAttribute("organization", organization);
    return "employee";
  }

已知:
我知道为什么不注入department.name,但是我不确定如何解决它。如何将部门名称从外部循环注入到内部循环,该内部循环在下面的c:foreach的员工列表中运行?或者如何以某种方式将其绑定到每个员工。我怀疑它在这里:

Admin Departments:<br>
                    <c:forEach var="department" varStatus="status" items="${organization.adminDepartmentList}">
                    ______Dept: <c:out value="${department.name}" /><br>
                    <div class="checkbox-list">
                        <c:forEach var="employee" varStatus="status" items="${department.employeeList}">
                              <input type="checkbox" name="adminDepartmentList[${status.index}].employeeList" value="${employee.firstName}"> <c:out value="${employee.firstName}" /><br>
                        </c:forEach>
                    </div>
                    </c:forEach>

我尝试使用隐藏的输入来帮助创建命名部门,但没有帮助。

学分:

非常感谢您的合作:)

为简单起见,假定员工的名字是唯一的。而且department.name也是唯一的。谢谢。


问题答案:

新闻: 哦,天哪,我解决了。

缺少的部分: 隐藏的输入,告诉您要创建哪个部门以及要为其注入什么名称。

<form:hidden path="adminDepartmentList[${statusDepartment.index}].name"  value="${department.name}" />

将部门名称注入到spring之前创建的每个部门。

整体解决方案: department.jsp

<form:form name='f' action="employee.htm"  method='POST' commandName="organization">
              Organization Name: <c:out value="${organization.name}" /><br>
              Select Employees you want for your new Departments.
              Admin Departments:<br>
                  <c:forEach var="department" varStatus="statusDepartment" items="${organization.adminDepartmentList}">
                      ______Dept: <c:out value="${department.name}" /><br>
                      <div class="checkbox-list">
                            <form:hidden path="adminDepartmentList[${statusDepartment.index}].name"  value="${department.name}" />
                            <c:forEach var="employee" varStatus="statusEmployee" items="${department.employeeList}">
                                <form:checkbox path="adminDepartmentList[${statusDepartment.index}].employeeList" value="${employee.firstName}"/> <c:out value="${employee.firstName}" /><br>
                            </c:forEach>
                      </div>
                  </c:forEach>

                Employee Departments:<br>
                  <c:forEach var="department" varStatus="statusDepartment" items="${organization.employeeDepartmentList}">
                      ______Dept: <c:out value="${department.name}" /><br>
                      <div class="checkbox-list">
                            <form:hidden path="employeeDepartmentList[${statusDepartment.index}].name" value="${department.name}" />
                            <c:forEach var="employee" varStatus="statusEmployee" items="${department.employeeList}">
                                <form:checkbox path="employeeDepartmentList[${statusDepartment.index}].employeeList" value="${employee.firstName}"/> <c:out value="${employee.firstName}" /><br>
                            </c:forEach>
                      </div>
                  </c:forEach>

                    <button type="submit" class="btn btn-lg btn-primary btn-block">Next Step</button>
    </form:form>