我的猜测是你错过了在RoleEntity类的equals
和hashcode
方法的实现。
当绑定值的类型为array或java.util.Collection时,如果绑定的Collection中存在已配置的setValue(Object)值,则输入(复选框)会标记为“checked”。
这是正确的,但您在您需要equals
和hashcode
正确实施HashSet
存在。这条线
model.addAttribute("roleList", roleList);
:
就像一个快速测试,看看如果是这样的问题,请更换此行
model.addAttribute("roleList", userEntity.getRoles());
你让所有的复选框选中?如果是的话,那么你没有提供你自己的equals
和hashcode
,并使用默认值(从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;
}
}
角色类(通知equals
和hashcode
方法;如果你删除它们,例如不再工作):
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]"
,这可能会让你在稍后遇到另一种麻烦。
非常感谢,Bogdan。这个回应真的有帮助!但是,只有在将用户角色添加到视图时,才会检查复选框:model.addAttribute(“roleList”,userEntity.getRoles());但它不适用于所有角色。 – 2012-01-09 22:55:53
@Paul Kuhn:不客气。我已经添加了一些解释以回应您的评论,以使答案更好。 [Here](http://tutorials.jenkov.com/java-collections/hashcode-equals.html)是一个更详细的演示文稿。希望它有助于进一步解释导致行为的原因。 – Bogdan 2012-01-10 20:55:31