8.3 SpringMVC参数绑定数组和集合
在批量修改用户操作时,前端请求传递过来的数据可能是各种类型的数据,比如int,String等,也可能是Java实体类或者数组等数据类型,但是数组只能绑定相同数据类型的数据,所以前端请求不同数据类型的数据时,我们也可以使用集合进行数据绑定,绑定集合的类型有:List、Set、Map等等。
在这里我们主要介绍数组和集合的springMVC数据绑定。
8.4案例SpringMVC参数绑定数组
本程序需求如下:假设我们有一个数据库表,表中有一些数据,我们需要对这些数据进行批量操作,比如批量删除操作。
为实现该功能,我们使用Mybits反向工程生成基于Mapper接口编程的代码,并依据该反向工程编写业务类。下面是我们的数据库表结构及表中的数据:
--设置Mysql客户端中文编码 set character_set_database=utf8; set character_set_connection=utf8; set character_set_client=gbk; set character_set_results=gbk; set character_set_server=utf8; set character_set_system=utf8; set character_set_filesystem=binary; drop database hcpgdb; create database hcpgdb; use hcpgdb; create table menu( menuid int(32) primary key AUTO_INCREMENT, menuname varchar(20), superid int(32) )ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 一级菜单 insert into menu values(1,'首页',0); insert into menu values(null,'中心概况',0); insert into menu values(null,'中心业绩',0); insert into menu values(null,'中心公告',0); insert into menu values(null,'项目评估',0); insert into menu values(null,'人才招聘',0); insert into menu values(null,'联系我们',0); -- 二级菜单 insert into menu values(null,'业务主管单位',2); insert into menu values(null,'中心性质',2); insert into menu values(null,'中心宗旨',2); insert into menu values(null,'业务范围',2); insert into menu values(null,'专家团队',2); insert into menu values(null,'组织架构',2); |
在Mysql数据库hcpgdb里我们有一个menu表,里面存储网站菜单数据。
使用反向工程生成相应的Menu.java、MenuExample.java、MenuMapper.java、MenuMapper.xml文件并编写Menu类的业务类ApplicationContexter.java和MenuDao.java,其中MenuDao.java类代码如下:
MenuDao.java
package dao;
import java.util.ArrayList; import java.util.List; import entity.Menu; import entity.MenuExample; import mapper.MenuMapper; public class MenuDao { public List<Menu> getMenus(){ List<Menu> list=new ArrayList<Menu>(); MenuMapper mm=(MenuMapper) ApplicationContexter.getApplicationContext().getBean("MenuMapper"); list=mm.selectByExample(null); return list; } public List<Menu> delMenusByIds(List<Integer> ids){ List<Menu> list=new ArrayList<Menu>(); MenuMapper mm=(MenuMapper) ApplicationContexter.getApplicationContext().getBean("MenuMapper"); MenuExample me=new MenuExample(); me.createCriteria().andMenuidIn(ids); mm.deleteByExample(me); list=mm.selectByExample(null); return list; } } |
在MenuDao.java类代码中我们设计了两个方法,一个是用来查询数据库menu 表中的所有菜单信息,一个是用来根据参数数组中传递的菜单ID集合进行批量删除菜单信息。
接下来我们要使用SpringMVC和Mybits框架共同配合实现菜单信息的批量管理功能。
使用SpringMVC和Mybits框架整合的配置文件程序结构我们还需要在相应的目录里编写文件applicationContext.xml、db.properties、mybatis-config.xml、springmvc-config.xml、web.xml(文件详细内容请参阅第六、第七章),并导入相应的jar包。
需要的包如下:

这里的包包含了本书所需要的所有包,读者可全部导入。
我们生成如下的程序目录结构:

这个程序我们中,其中的控制器类MenuEditController.java代码如下:
package controller; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import entity.Menu; import dao.MenuDao; @Controller @RequestMapping("/menu") public class MenuEditController { @RequestMapping("/menulist") public String listmenu(Model model){ List<Menu> list=new MenuDao().getMenus(); model.addAttribute("menus", list); return "editmenu"; } @RequestMapping("/delmenus") public String delmenu(Model model,Integer[] menuids){ List<Integer> menulist=new ArrayList<Integer>(); for(int i=0;i<menuids.length;i++){ menulist.add(menuids[i]); } new MenuDao().delMenusByIds(menulist); List<Menu> list=new MenuDao().getMenus(); model.addAttribute("menus", list); return "editmenu"; } } |
在控制器类里我们将控制器类URL注解为“/menu”,并且设计了两个响应方法listmenu(Model model)和delmenu(Model model,Integer[] menuids)。其中方法listmenu(Model model)的URL注解为“/menulist”,delmenu(Model model,Integer[] menuids) 的URL注解为“/delmenus”。
在响应方法listmenu(Model model)中,我们先使用MenuDao类的查询方法查询出所有菜单信息放入list并把list对象放入参数model对象中以便于传递给下一张视图editmenu.jsp。在响应方法 delmenu(Model model,Integer[] menuids)中,我们先从参数menuids中取出表单中传递过来的菜单ID数组,然后使用MenuDao类的删除功能进行批量操作,之后再从数据库中查询操作后的菜单数据并放入参数model对象中以便于传递给下一张视图editmenu.jsp。
在这里我们还有一个重要文件,那就是editmenu.jsp,该文件一方面应该显示数据库中菜单表中的菜单信息,另一方面在页面中应该有批量操作的功能,比如全选全不选等操作,而且在选中一些信息后点击提交按钮时应该将选中的数据提交到服务器。其代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Insert title here</title> </head> <body> <script type="text/javascript"> function selectallid(){ var selectall=document.getElementById("selectall"); var cbox=document.getElementsByName("menuids"); for(i=0;i<cbox.length;i++){ if(selectall.checked!=true) cbox[i].checked=false; else cbox[i].checked=true; } } </script> <form action="delmenus" method="post"> <input type="submit" value="删 除"/> <table border=1 width="500"> <tr><th><input name="selectall" type="checkbox" id="selectall" onclick="selectallid();" ></th><th>ID</th><th>菜单名称</th><th>父菜单ID</th></tr> <c:forEach items="${menus }" var="menu"> <tr> <td><input name="menuids" type="checkbox" value="${menu.menuid }" id="selectall" ></td> <td>${menu.menuid }</td> <td>${menu.menuname }</td> <td>${menu.superid }</td> </tr> </c:forEach> </table> </form> </body> </html> |
代码“<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>”和代码
“<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>”用来引用JSTL库,JSTL库需要我们导入jstl.jar包和standard.jar包。
代码<c:forEach items="${menus }" var="menu">是符合Jstl语法的遍历(循环)语句,其属性items的值是一个数组或集合,属性var的值是遍历时的临时变量menu,由于EL表达式${menus }代表控制器传递过来的控制器类方法的参数Model对象中存储的菜单集合。利用Jstl的循环语句,我们就可以显示该对象中的信息了。
在这里我们使用javaScript实现了全选和全不选功能,在我们选中其中一部分记录并点击删除按钮后,就把选中的数据信息提交给控制器类中的第二个响应方法,该方法执行删除操作后又跳转回本视图。
需要注意的是我们访问editmenu.jsp文件时不能直接输入editmenu.jsp的URL进行访问,因为直接访问时editmenu.jsp没有接收任何数据。我们应该从控制器类的方法的URL那里进行访问。如下图:
直接输入editmenu.jsp的URL进行访问我们看到没有数据显示:

从控制器类的方法的URL那里进行访问我们看到有数据显示:

在本页面中我们选中ID为2、3、4的数据点击删除按钮我们看到结果如下:

从运行结果看,选中的信息正确的删除了。

