2012-01-02 57 views
13

Tôi biết đã có câu hỏi về chủ đề này nhưng tôi chưa tìm ra cách giải quyết vấn đề sau:Sử dụng biểu mẫu MVC mùa xuân: hộp kiểm để ràng buộc dữ liệu

Tôi có mối quan hệ người dùng/vai trò và tôi muốn liệt kê tất cả các vai trò có sẵn trong một JSP như các mục hộp kiểm, nơi các hộp kiểm được gán cho người dùng được chọn. Tuy nhiên, các mục phù hợp không được kiểm tra (ở đây tôi đang sử dụng Spring 3.1).

Extract từ đối tượng sử dụng:

private Set<RoleEntity> roles = new HashSet<RoleEntity>(); 

Extract từ Controller Spring (thêm đối tượng người dùng và danh sách vai Model):

UserEntity userEntity = userEntityService.findById(UserEntity.class, new Long(id)); 
model.addAttribute("userAttribute", userEntity); 

List<RoleEntity> roleList = roleEntityService.findAll(); 
model.addAttribute("roleList", roleList); 

Extract từ JSP:

<form:form modelAttribute="userAttribute" method="POST" action="${saveUrl}"> 
... 

    <table align="center"> 
     <tr> 
      <td>ID</td> 
      <td>Role Name</td> 
     </tr> 
     <c:forEach items="${roleList}" var="role" varStatus="status"> 
      <tr> 
       <td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td> 
       <td><c:out value="${role.name}" /></td> 
      </tr> 
     </c:forEach> 
    </table> 

... 
</form:form> 

Tài liệu Spring MVC nói điều này: Khi giá trị giới hạn là của mảng kiểu hoặc java.util.Collection, đầu vào (hộp kiểm) được đánh dấu là 'đã chọn' nếu giá trị setValue (Object) được cấu hình có trong Bộ sưu tập bị ràng buộc.

Đó không phải là trường hợp ở đây phải không? Tôi đang thiếu gì ở đây?

Cảm ơn rất nhiều.

Paul

Trả lời

20

tôi đoán là bạn đang thiếu việc thực hiện cho equalshashcode phương pháp trên lớp RoleEntity.

Khi giá trị bị ràng buộc thuộc loại mảng hoặc java.util.Collection, đầu vào (hộp kiểm) được đánh dấu là 'đã chọn' nếu giá trị setValue (Object) được đặt cấu hình có trong Bộ sưu tập bị ràng buộc.

này là đúng, nhưng để kiểm tra sự hiện diện trong một HashSet bạn cần equalshashcode thực hiện một cách chính xác.

Cũng giống như một thử nghiệm nhanh để xem nếu đó là vấn đề, thay thế dòng này:

model.addAttribute("roleList", roleList); 

với dòng này:

model.addAttribute("roleList", userEntity.getRoles()); 

Bạn có nhận được tất cả các hộp kiểm của bạn kiểm tra? Nếu có, sau đó bạn không cung cấp equalshashcode của riêng mình và các giá trị mặc định được sử dụng (những thứ được kế thừa từ Object).

Giá trị mặc định equals so sánh danh tính có nghĩa là biến chứa cùng một phiên bản với một biến khác. Bình đẳng có nghĩa là hai đối tượng khác nhau chứa cùng một trạng thái hoặc có cùng ý nghĩa, để nói.

Sử dụng model.addAttribute("roleList", userEntity.getRoles()) kích hoạt phương thức mặc định equals để trả về true vì danh sách và giá trị bạn kiểm tra sự hiện diện trong danh sách giống nhau (hai đối tượng giống nhau luôn bằng nhau).

Nhưng trong trường hợp của bạn, bạn sử dụng userEntityService.findById cho một và roleEntityService.findAll cho người khác có nghĩa là các đối tượng khác nhau. Tại thời điểm này, bạn phải sử dụng một kiểm tra bình đẳng thích hợp như trái ngược với danh tính.

Bạn có thực hiện equals/hashcode không?

Dựa trên mã của bạn, đây là một ví dụ mà làm việc:

Bộ điều khiển:

import java.util.Arrays; 
import java.util.Collections; 
import java.util.HashSet; 
import java.util.List; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

@Controller 
public class SomeController { 
    @RequestMapping(value = "/something", method = { RequestMethod.GET, RequestMethod.POST }) 
    public String handle(Model model) { 

     UserEntity userEntity = new UserEntity(); 
     userEntity.setRoles(new HashSet<RoleEntity>()); 
     Collections.addAll(userEntity.getRoles(), 
           new RoleEntity(1, "one"), 
           new RoleEntity(3, "three")); 
     model.addAttribute("userAttribute", userEntity);   

     List<RoleEntity> roleList = Arrays.asList(
             new RoleEntity(1, "one"), 
             new RoleEntity(2, "two"), 
             new RoleEntity(3, "three") 
            ); 
     model.addAttribute("roleList", roleList); 

     return "view"; 
    } 
} 

lớp User:

import java.util.HashSet; 
import java.util.Set; 

public class UserEntity { 
    private Set<RoleEntity> roles = new HashSet<RoleEntity>(); 

    public Set<RoleEntity> getRoles() { 
     return roles; 
    } 
    public void setRoles(Set<RoleEntity> roles) { 
     this.roles = roles; 
    } 
} 

Vai trò lớp (thông báo các equalshashcode phương pháp; nếu bạn xóa chúng, Ví dụ không còn hoạt động):

public class RoleEntity { 
    private long id; 
    private String name; 

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

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

    public RoleEntity(long id, String name) { 
     this.id = id; 
     this.name = name; 
    } 

    public long getId() { 
     return id; 
    } 
    public void setId(long id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 

Xem:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<form:form modelAttribute="userAttribute" method="POST" action="/something"> 
    <table align="center"> 
     <tr> 
      <td>ID</td> 
      <td>Role Name</td> 
     </tr> 
     <c:forEach items="${roleList}" var="role"> 
      <tr> 
       <td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td> 
       <td><c:out value="${role.name}" /></td> 
      </tr> 
     </c:forEach> 
    </table> 
</form:form> 

T.B. Chỉ cần một quan sát về JSP của bạn. Nếu bạn làm value="${role}" cho biểu mẫu của mình: hãy chọn hộp kiểm, bạn sẽ nhận được các thuộc tính hộp kiểm HTML như value="[email protected]" có thể khiến bạn gặp phải một sự cố khác sau này.

+0

Cảm ơn rất nhiều, Bogdan. Phản ứng này thực sự đã giúp !! Tuy nhiên, các hộp kiểm chỉ được kiểm tra khi tôi thêm vai trò người dùng vào khung nhìn: model.addAttribute ("roleList", userEntity.getRoles()); nhưng nó không hoạt động với tất cả các vai trò. –

+0

@Paul Kuhn: Bạn được chào đón. Tôi đã thêm một vài lời giải thích khi trả lời nhận xét của bạn để làm cho câu trả lời tốt hơn. [Ở đây] (http://tutorials.jenkov.com/java-collections/hashcode-equals.html) là bản trình bày chi tiết hơn. Hy vọng nó giúp giải thích thêm những gì đã gây ra hành vi. – Bogdan

Các vấn đề liên quan