问题描述
我知道有关此主题的问题已经存在,但是我还没有弄清楚如何解决以下问题:
I know there have been already questions around this topic, but I have not figured out how to solve the following issue:
我有一个用户/角色关系,我想列出JSP中所有可用的角色作为复选框项目,在其中选择了用户分配的复选框.但是,不检查匹配项(这里我使用的是Spring 3.1).
I have a user/roles relationship and I want to list all available roles in a JSP as checkbox items, where the users assigned checkboxes are selected. However, the matching items are not checked (here I am using Spring 3.1).
从User对象中提取:
Extract from the User object:
private Set<RoleEntity> roles = new HashSet<RoleEntity>();
从Spring Controller中提取(将用户对象和角色列表添加到模型中):
Extract from the Spring Controller (adding user object and role list to Model):
UserEntity userEntity = userEntityService.findById(UserEntity.class, new Long(id));
model.addAttribute("userAttribute", userEntity);
List<RoleEntity> roleList = roleEntityService.findAll();
model.addAttribute("roleList", roleList);
从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>
Spring MVC文档说:当绑定值是array或java.util.Collection类型时,如果绑定的Collection中存在已配置的setValue(Object)值,则输入(复选框)被标记为已选中".
The Spring MVC documentation says this:When the bound value is of type array or java.util.Collection, the input(checkbox) is marked as 'checked' if the configured setValue(Object) value is present in the bound Collection.
不是这样吗?我在这里想念什么?
Isn't that the case here? What am I missing here?
非常感谢.
保罗
推荐答案
我的猜测是您缺少RoleEntity类上equals
和hashcode
方法的实现.
My guess is you are missing the implementation for the equals
and hashcode
methods on the RoleEntity class.
这是正确的,但是要检查HashSet
中是否存在,您需要正确实现equals
和hashcode
.
This is correct, but to check for presence in a HashSet
you need equals
and hashcode
implemented correctly.
只是为了快速检查一下是否是问题所在,请替换此行:
Just as a quick test to see if that's the problem, replace this line:
model.addAttribute("roleList", roleList);
有这行:
model.addAttribute("roleList", userEntity.getRoles());
您是否选中了所有复选框?如果是,则您没有提供自己的equals
和hashcode
,而是使用默认值(继承自Object
的默认值).
Do you get all your checkboxes checked? If yes, then you didn't provide your own equals
and hashcode
and the default ones are used (those inherited from Object
).
默认值equals
比较身份,这意味着一个变量与另一个变量拥有相同的实例.相等意味着可以说两个不同的对象包含相同的状态或具有相同的含义.
The default equals
compares identity which means that a variable holds the same instance as another variable. Equality means two different object contain the same state or have the same meaning, so to speak.
使用model.addAttribute("roleList", userEntity.getRoles())
会触发默认的equals
方法返回true,因为列表和您检查列表中是否存在的值是相同的(两个相同的对象始终相等).
Using model.addAttribute("roleList", userEntity.getRoles())
triggers the default equals
method to return true because the list and values you check for presence in the list are identical (two identical objects are always equal).
但是在您的情况下,您将userEntityService.findById
用于一个,将roleEntityService.findAll
用于另一个,这表示不同的对象.此时,您必须使用适当的相等性测试,而不是身份.
But in your case you use userEntityService.findById
for one and roleEntityService.findAll
for the other which means different objects. At this point you have to use a proper equality test as opposed to identity.
您实现了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;
}
}
Roles类(注意equals
和hashcode
方法;如果删除它们,该示例将不再起作用)
Roles class (notice the equals
and hashcode
methods; if you remove them, the example no longer works):
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>
P.S.只是关于JSP的一个观察结果.如果对复选框执行value="${role}"
,您将获得value="your.pack.age.declaration.RoleEntity@1"
这样的HTML复选框属性,这以后可能会给您带来另一种麻烦.
P.S. Just one observation about your JSP. If you do value="${role}"
for your form:checkbox you will get HTML checkbox attributes like value="your.pack.age.declaration.RoleEntity@1"
which might get you in another sort of trouble later on.
这篇关于Spring MVC使用form:checkbox绑定数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!