文档章节

SpringMVC Checkbox 对List<object> 数据绑定

Vincent-Duan
 Vincent-Duan
发布于 2015/06/08 12:11
字数 721
阅读 1917
收藏 4

http://stackoverflow.com/questions/8700339/spring-mvc-usage-of-formcheckbox-to-bind-data

I know there have been already questions around this topic, but I have not figured out how to solve the following issue:

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

Extract from the User object:

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

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

Extract from the 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>

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?

My guess is you are missing the implementation for the equals and hashcode methods on the RoleEntity class.

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.

This is correct, but to check for presence in a HashSet you need equals and hashcodeimplemented correctly.

Just as a quick test to see if that's the problem, replace this line:

model.addAttribute("roleList", roleList);

with this line:

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

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

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.

Using model.addAttribute("roleList", userEntity.getRoles()) triggers the default equalsmethod to return true because the list and values you check for presence in the list are identical (two identical objects are always equal).

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.

Do you have equals/hashcode implemented?

Based on your code, here is an example that works:

Controller:

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

User class:

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

View:

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


© 著作权归作者所有

共有 人打赏支持
Vincent-Duan

Vincent-Duan

粉丝 9
博文 307
码字总数 100710
作品 0
海淀
私信 提问
spring 接收json数据 请教

请先参照附图的设计 和前台页面(别笑话我,笑话也没事 :-) ) spring 的controller的方法: @RequestMapping(value = "jsoncreate", method = RequestMethod.POST) @ResponseBody public Ma...

岽茗
2016/01/22
961
10
HibernateCallback

HibernateTemplate还提供一种更加灵活的方式来操作数据库,通过这种方式可以完全使用Hibernate的操作方式。HibernateTemplate的灵活访问方式是通过如下两个方法完成: q Object execute(Hib...

疯狂的艺术家
2011/06/12
0
0
5:spring mvc 数据类型转换

SpringMVC如何实现数据类型转换 1、类型转换:首先表单数据(全部是字符串)通过WebDataBinder进行绑定到命令对象,内部通过Converter SPI实现; 2、数据验证:使用JSR-303验证框架进行验证;...

小杰java
2017/10/18
0
0
ListView设置点击效果

我们先看一下一个 ListView绑定6行数据,每行数据上包括了三个控件:TextView,CheckBox,Button,运行效果如下图所示: 绑定代码: ListView lstView = (ListView) this.findViewById(R.id.lis...

长平狐
2012/09/03
2.5K
0
SpringMVC开发 知识点速查

SpringMVC入门 什么是SpringMVC 实现MVC设计模式的框架 SpringMVC核心组件 DispatcherServlet 前置控制器,调度 Handler 处理器,完成具体业务逻辑 HandlerMapping 将请求映射到Handler,映射...

linxinzhe
05/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

我是如何将博客转成PDF的

前言 只有光头才能变强 之前有读者问过我:“3y你的博客有没有电子版的呀?我想要份电子版的”。我说:“没有啊,我没有弄过电子版的,我这边有个文章导航页面,你可以去文章导航去找来看呀”...

Java3y
13分钟前
0
0
nginx的一些总结

Linux下安装Nginx完整教程及常见错误解决方案 1.Nginx安装环境 Nginx是C语言开发,建议在linux上运行,本教程使用Centos7.0作为安装环境. 1)gcc 安装nginx需要先将官网下载的源码进行编译,编译...

Yao--靠自己
20分钟前
0
0
Predicate函数式接口

Predicate接口主要用于流的筛选,比如在filter方法中传入Predicate判断。 作为函数式接口,这里居然有三个default方法,一个static方法,子孙满堂! 正统的接口方法,就是boolean test(T t)...

woshixin
21分钟前
0
0
sql 开窗函数

开窗函数:在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成。为了解决这些问题,在 2003 年 ISO SQL 标准加入了开窗函数,开窗函数...

hblt-j
31分钟前
1
0
使用Vue动态生成form表单的实例代码

具有数据收集、校验和提交功能的表单生成器,包含复选框、单选框、输入框、下拉选择框等元素以及,省市区三级联动,时间选择,日期选择,颜色选择,文件/图片上传功能,支持事件扩展。 欢迎大家s...

嫣然丫丫丫
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部