2016-09-09 47 views
0

我想這樣做;如何將數據綁定到CheckBox使用Spring MVC中的多對多註釋

我有一個工作來改進學習Spring,Hibernate和JPA的CRUD應用程序。所以我想做多對多的例子,但我要求某人這樣做。

我想獲得員工的駕駛執照和更新信息。我可以使用Spring forEach將員工的數據從數據庫獲取到網頁中的CheckBox。如果員工擁有哪個駕駛執照,則必須檢查關係型CheckBox。我可以更新這些信息。

例如,員工已獲得「A1」和「M」級駕駛執照。我可以獲取和綁定數據。

我創建了「employees」,「driving_licenses」表。 我創建的 「employee_driving_licenses」 表的商店僱員的駕駛執照:

員工:

id   int 
last_name nvarchar(20) 
first_name nvarchar(10) 

driving_licenses:

id  int 
code nvarchar(5) 

employee_driving_licenses:

employee_id   int 
driving_license_id int 

我創建表的模型類並添加了JPA註釋。我有員工和DrivingLicense實體Java類:

Employee.java

@Entity 
@Table(name = "employees") 
public class Employee { 

    private int id; 
    private String last_name; 
    private String first_name; 
    private java.util.Collection<DrivingLicense> driving_licenses = new HashSet<DrivingLicense>(); 

    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Id 
    @Column 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @NotEmpty(message = "Please enter Last Name") 
    @Column 
    public String getLast_name() { 
     return last_name; 
    } 

    public void setLast_name(String last_name) { 
     this.last_name = last_name; 
    } 

    @NotEmpty(message = "Please enter First Name") 
    @Column 
    public String getFirst_name() { 
     return first_name; 
    } 

    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "employees") 
    public java.util.Collection<DrivingLicense> getDriving_licenses() { 
     return driving_licenses; 
    } 

    public void setDriving_licenses(
     java.util.Collection<DrivingLicense> driving_licenses) {this.driving_licenses = driving_licenses; 
    } 
} 

DrivingLicense.java

@Entity 
@Table(name = "driving_licenses") 
public class DrivingLicense { 

    private int id; 
    private String code; 
    private java.util.Collection<Employee> employees = new HashSet<Employee>(); 

    @Override 
    public int hashCode() { 
     return new Long(id).hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) { 
       return false; 
     } 
     if (!(obj instanceof DrivingLicense)) { 
       return false; 
     } 
     return this.id == ((DrivingLicense) obj).getId(); 
    } 

    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Id 
    @Column 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @Column 
    public String getCode() { 
     return code; 
    } 

    public void setCode(String code) { 
     this.code = code; 
    } 

    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) 
    @JoinTable(name = "employee_driving_licenses", joinColumns = { @JoinColumn(name = "driving_license_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "employee_id", nullable = false, updatable = false) }) 
    public java.util.Collection<Employee> getEmployees() { 
     return employees; 
    } 

    public void setEmployees(java.util.Collection<Employee> employees) { 
     this.employees = employees; 
    } 
} 

我創建的應用程序DAO,服務,控制器和視圖類/頁。

EmployeeController.java:

@RequestMapping(value = "index", method = RequestMethod.POST) 
public String employee(@Valid @ModelAttribute("employee") Employee employee, 
    BindingResult result, @RequestParam String action, 
    java.util.Map<String, Object> map) { 

    boolean isValid = true; 
    if (result.hasErrors()) { 
     isValid = false; 
    } 

    Employee employeeResult = new Employee(); 
    switch (action.toLowerCase()) { 
     case "add": 
      if (isValid) 
       employeeService.add(employee); 
      employeeResult = employee; 
     break; 

     case "edit": 
      if (isValid) 
       employeeService.edit(employee); 
      employeeResult = employee; 
     break; 
    } 
    map.put("drivingLicenseList", drivingLicenseService.findActiveDrivingLicense()); 
    map.put("employee", employeeResult); 
    map.put("activeEmployeeList", employeeService.findActiveEmployees()); 
    return "employee"; 
} 

employee.jsp:

<c:forEach var="drive_licenses" items="${drivingLicenseList}"> 
    <form:checkbox path="driving_licenses" 
    value="${drive_licenses }" label="${drive_licenses.code }" /> 
</c:forEach> 

當我想更新員工的駕駛執照,我收到如下錯誤代碼:

{[email protected], org.springframework.validation.BindingResult.employee=org.springframework.validation.BeanPropertyBindingResult:  1 errors 
Field error in object 'employee' on field 'driving_licenses': rejected value  [[email protected],[email protected],[email protected],com.ay.model.Driving [email protected]]; codes  [typeMismatch.employee.driving_licenses,typeMismatch.driving_licenses,typeMismatch.java.util.Collection,typeMis match]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes  [employee.driving_licenses,driving_licenses]; arguments []; default message [driving_licenses]]; default  message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Collection'  for property 'driving_licenses'; nested exception is java.lang.IllegalStateException: Cannot convert value of  type [java.lang.String] to required type [com.ay.model.DrivingLicense] for property 'driving_licenses[0]': no  matching editors or conversion strategy found]} 

如何獲得收集類型的值?請給我建議。

還有,如果我employee.jsp的網頁上添加該代碼

value="${drive_licenses }" 

,我可以看到瀏覽器對象值通常。其實首先,我加入這個代碼

value="${drive_licenses.id }" 

但員工的駕駛執照沒有上的複選框,每個的CheckBox值是空了檢查。什麼是真正的語法?

謝謝你的支持。

回答

0

有太多的零件。大致爲:

一個:創建一個包裝形式:

public class EmployeeForm{ 
    private Employee employee; 

    //Driving licence needs a 'boolean' selected field 
    //Mark as @Transient so not persisted 
    //Otherwise create another wrapper/dto which has this boolean field 
    //Spring MVC can only bind to indexed fields e.g. List 
    private List<DrivingLicence> allAvailableLicences; 

    public EmployeeForm(Employee employee, Collecion<DrivingLicence> licenes){ 
     //set instance vars 
    } 

    //getters 
    //setters 
} 

兩個:以下內容添加到您的控制器:

//CALLED ON BOTH GET AND POST TO SET UP THE FORM 
//FOR EDITING EXISTING EMPLOYEE REPLACE NEW EMPLOYEE WITH THE RELEVANT LOOKUP 
@ModelAttribute("employeeForm") 
public EmployeeForm getEmployeeForm(@RequestParam("employeeId", required = false) Long employeeId){ 
    return new EmployeeForm(new Employee(), drivingLicenseService.findActiveDrivingLicense()); 

} 

更改您的JSP表單綁定到employeeForm:你可以使用嵌套屬性,例如employee.name前面的路徑屬性。對於綁定許可證,您需要使用下面的索引符號,即將列表中的索引x處的許可證設置爲選中狀態。

<c:forEach var="licence" items="${employeeForm.allAvailableLicences}" varStatus="loop"> 
    <form:checkbox path="licence[${loop.index]}.selected" label="${licence.code }" /> 
</c:forEach> 

四:

更新您的表單提交處理程序:

@RequestMapping(value = "index", method = RequestMethod.POST) 
public String employee(@Valid @ModelAttribute("employeeForm") EmployeeForm employeeForm, 
    BindingResult result, @RequestParam String action) { 

    //validation etc 

    Employee employee = employeeForm.getEmployee(); 

    for(DrivingLicence licence : employeeForm.getAllAvailableLicences()){ 
     //our indexed foem check box set the 'selected' field true 
     //if selected add to the employee 
    } 

    //save updated employee 

    return "nextPage"; 
} 
+0

我真的不知道如何使用「路徑選擇的屬性模型類和JSP表單輸入數據之間的綁定=」許可證[$ {loop.index]}。selected「'。我如何轉換DAO類的數據? – RuudVanNistelrooy

+0

也許應該是path =「employeeForm.allAvailableLicences [{loop.index}]。selected」必須有數百個綁定到索引字段的例子。只要確保許可證有一個臨時布爾字段'selected'並將true作爲複選框值傳遞。 –