2012-01-02 40 views
13

我知道已经有围绕这一话题已经问题,但我还没有想出如何解决了以下问题:形式的Spring MVC的用法:复选框,将数据绑定

我有一个用户/角色的关系和我想要在JSP中列出所有可用的角色作为复选框项目,其中选择了用户分配复选框。但是,匹配的项目不会被检查(这里我使用的是Spring 3.1)。从用户对象

提取物:从JSP

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

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

提取物::

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

从Spring控制器提取物(添加用户对象和角色列表模型)

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

Spring MVC文档中提到: 当绑定值为类型数组或java.util.Collection,如果绑定的Collection中存在已配置的setValue(Object)值,则输入(复选框)将被标记为“已检查”。

这不是这种情况吗?我在这里错过了什么?

非常感谢。

保罗

回答

20

我的猜测是你错过了在RoleEntity类equalshashcode方法的实现。

当绑定值的类型为array或java.util.Collection时,如果绑定的Collection中存在已配置的setValue(Object)值,则输入(复选框)会标记为“checked”。

这是正确的,但您在您需要equalshashcode正确实施HashSet存在。这条线

model.addAttribute("roleList", roleList); 

就像一个快速测试,看看如果是这样的问题,请更换此行

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

你让所有的复选框选中?如果是的话,那么你没有提供你自己的equalshashcode,并使用默认值(从Object继承)。

默认equals比较标识,这意味着一个变量与另一个变量保持相同的实例。平等意味着两个不同的对象包含相同的状态或具有相同的含义,可以这么说。

使用model.addAttribute("roleList", userEntity.getRoles())会触发默认的equals方法返回true,因为检查列表中存在的列表和值是否相同(两个相同的对象始终相等)。

但在你的情况下,你使用userEntityService.findById为一个和roleEntityService.findAll为另一个意味着不同的对象。此时你必须使用适当的平等测试而不是身份。

您是否有equals/hashcode执行?

基于您的代码,这里是工作的例子:

控制器:

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"; 
    } 
} 

用户等级:

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

角色类(通知equalshashcode方法;如果你删除它们,例如不再工作):

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

查看:

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

附:只有一个关于你的JSP的观察。如果你为你的表单做了value="${role}":复选框,你会得到HTML复选框属性,例如value="[email protected]",这可能会让你在稍后遇到另一种麻烦。

+0

非常感谢,Bogdan。这个回应真的有帮助!但是,只有在将用户角色添加到视图时,才会检查复选框:model.addAttribute(“roleList”,userEntity.getRoles());但它不适用于所有角色。 – 2012-01-09 22:55:53

+0

@Paul Kuhn:不客气。我已经添加了一些解释以回应您的评论,以使答案更好。 [Here](http://tutorials.jenkov.com/java-collections/hashcode-equals.html)是一个更详细的演示文稿。希望它有助于进一步解释导致行为的原因。 – Bogdan 2012-01-10 20:55:31