- 浏览: 1655949 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (405)
- C/C++ (16)
- Linux (60)
- Algorithm (41)
- ACM (8)
- Ruby (39)
- Ruby on Rails (6)
- FP (2)
- Java SE (39)
- Java EE (6)
- Spring (11)
- Hibernate (1)
- Struts (1)
- Ajax (5)
- php (2)
- Data/Web Mining (20)
- Search Engine (19)
- NLP (2)
- Machine Learning (23)
- R (0)
- Database (10)
- Data Structure (6)
- Design Pattern (16)
- Hadoop (2)
- Browser (0)
- Firefox plugin/XPCOM (8)
- Eclise development (5)
- Architecture (1)
- Server (1)
- Cache (6)
- Code Generation (3)
- Open Source Tool (5)
- Develope Tools (5)
- 读书笔记 (7)
- 备忘 (4)
- 情感 (4)
- Others (20)
- python (0)
最新评论
-
532870393:
请问下,这本书是基于Hadoop1还是Hadoop2?
Hadoop in Action简单笔记(一) -
dongbiying:
不懂呀。。
十大常用数据结构 -
bing_it:
...
使用Spring MVC HandlerExceptionResolver处理异常 -
一别梦心:
按照上面的执行,文件确实是更新了,但是还是找不到kernel, ...
virtualbox 4.08安装虚机Ubuntu11.04增强功能失败解决方法 -
dsjt:
楼主spring 什么版本,我的3.1 ,xml中配置 < ...
使用Spring MVC HandlerExceptionResolver处理异常
最近遇到一个需求,使用Spring MVC 3,需要绑定动态列表成员。Google了好多文章,没有找到完美的解决方案,绑定到不成问题,主要是动态添加、删除导致绑定的列表下标,在提交之前需要进行normalize,使用js进行normalize可行,但是费劲而且如果有对表单新的修改导致已有的js出现错误,本文提供了一个简单可行的易于维护的方法:
在添加的时候,我们根据当前条目的数量,计算新添加条目的下标。
在删除的时候,使用js将删除的条目隐藏,并将删除列表的下标记录到隐藏字段中。
这样在后台,我们只需要将删除的条目,按照记录在隐藏字段的下标删除,然后再保存即可。
关于绑定动态列表,在Spring 2.5中,不能使用普通的List,必须使用AutoPopulatingList进行绑定,否则会导致OutOfBoundException,Spring 3提供了Auto Grown的功能,但还仅限于List和Array,map和set还不能Auto Grown。
下面以一个简单的订单修改的例子说明如何进行动态列表绑定:
一个订单,有很多订单条目,用户可以修改订单,动态删除或者添加订单条目。
先看看model:
订单类,一个订单有一个订单列表:
订单条目类:
我们的控制器使用@ModelAttribute注解和表单绑定:
edit_order.jsp的表单和js添加、删除:
在Serice类中我们只是简单的准备数据和打印出结果查看效果:
BTW:Java的自动拆装箱要注意,特别是List#remove有两个重载的方法,
remove(Object) remove(int),这个必须手工拆箱。
好像不可以,绑定的需要能够按照下标访问的,而Set本身不能确保有序,所以不能下标访问。最好在VO中使用List绑定,然后和PO的Set转换一下。
在添加的时候,我们根据当前条目的数量,计算新添加条目的下标。
在删除的时候,使用js将删除的条目隐藏,并将删除列表的下标记录到隐藏字段中。
这样在后台,我们只需要将删除的条目,按照记录在隐藏字段的下标删除,然后再保存即可。
关于绑定动态列表,在Spring 2.5中,不能使用普通的List,必须使用AutoPopulatingList进行绑定,否则会导致OutOfBoundException,Spring 3提供了Auto Grown的功能,但还仅限于List和Array,map和set还不能Auto Grown。
下面以一个简单的订单修改的例子说明如何进行动态列表绑定:
一个订单,有很多订单条目,用户可以修改订单,动态删除或者添加订单条目。
先看看model:
订单类,一个订单有一个订单列表:
package com.qunar.advertisement.advertiser.model; import java.util.List; /** * Author: fuliang * http://fuliang.iteye.com */ public class Order { private Long id; private String name; private List<OrderItem> orderItems; public void setId(Long id) { this.id = id; } public Long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setOrderItems(List<OrderItem> orderItems) { this.orderItems = orderItems; } public List<OrderItem> getOrderItems() { return orderItems; } }
订单条目类:
package com.qunar.advertisement.advertiser.model; /** * Author: fuliang * http://fuliang.iteye.com */ public class OrderItem { private Long id; private String product; private Integer price; public void setId(Long id) { this.id = id; } public Long getId() { return id; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public void setProduct(String product) { this.product = product; } public String getProduct() { return product; } }
我们的控制器使用@ModelAttribute注解和表单绑定:
package com.qunar.advertisement.advertiser.controller; import java.util.Collections; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import com.qunar.advertisement.advertiser.model.Order; import com.qunar.advertisement.advertiser.service.OrderManger; /** * Author: fuliang * http://fuliang.iteye.com */ @Controller @RequestMapping("/orders") public class OrderController { private OrderManger orderManager; @Autowired public void setOrderManger(OrderManger orderManager){ this.orderManager = orderManager; } @RequestMapping("/edit/{id}") public ModelAndView edit(@PathVariable("id") Long id){ return new ModelAndView("/orders/edit_order",Collections.singletonMap("order", orderManager.getOrderById(id))); } @RequestMapping("/update") public ModelAndView update(@ModelAttribute("order") @Valid Order order,@RequestParam(value="deletedIndexes",required=false) List<Integer> deletedIndexes){ orderManager.update(order,deletedIndexes); return new ModelAndView("/orders/home"); } }
edit_order.jsp的表单和js添加、删除:
<%@ 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/jstl/fn" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <jsp:include page="../base.jsp"></jsp:include> <head> <script src="js/jquery-1.3.1.js" type="text/javascript"></script> <title>Order Home</title> <script type="text/javascript"> function deleteItem(itemIndex){ $('#item_' + itemIndex).hide(); $('#deletedIndexes').append("<input type='hidden' name='deletedIndexes' value='" + itemIndex + "'"); } function addItem(){ var itemCnt = parseInt($('#itemCnt').val()); var newItem = '<tr id="item_' + itemCnt + '">' + '<th>订单条目' + (itemCnt + 1)+ '</th>' + '<td><input type="hidden" name="orderItems[' + itemCnt + '].id"/>' + '<input type="text" name="orderItems[' + itemCnt + '].product"/>' + '</td>' + '<td><input type="text" name="orderItems[' + itemCnt + '].price"/></td>' + '<td><a href="javascript:void(0)" onclick="deleteItem('+ itemCnt + ')">删除条目</a></td>' + '</tr>'; $('#item_' + (itemCnt-1)).after(newItem); $('#itemCnt').val(itemCnt + 1); } </script> </head> <body> <div id="form"> <form:form commandName="order" id="orderForm" action="orders/update" method="post"> <form:hidden path="id"/> <div id="deletedIndexes" style="display:none;"> </div> <input type="hidden" value="${fn:length(order.orderItems)}" id="itemCnt"/> <table> <tr> <th>订单名</th> <td colspan="3"><form:input path="name"/></td> </tr> <c:forEach varStatus="vs" items="${order.orderItems}"> <tr id="item_${vs.index}"> <th>订单条目${vs.index + 1}</th> <td><form:hidden path="orderItems[${vs.index}].id"/> <form:input path="orderItems[${vs.index}].product"/> </td> <td><form:input path="orderItems[${vs.index}].price"/></td> <td><a href="javascript:void(0)" onclick="deleteItem('${vs.index}')">删除条目</a></td> </tr> </c:forEach> <tr> <td colspan="4" style="text-align:center"> <input type="submit" value="保存"/> <input type="button" value="添加订单条目" onclick="addItem()"/> </td> </tr> </table> </form:form> </div> </body> </html>
在Serice类中我们只是简单的准备数据和打印出结果查看效果:
package com.qunar.advertisement.advertiser.service; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; import com.qunar.advertisement.advertiser.model.Order; import com.qunar.advertisement.advertiser.model.OrderItem; /** * Author: fuliang * http://fuliang.iteye.com */ @Service public class OrderManger { //Simple data for test public Order getOrderById(Long id){ Order order = new Order(); order.setId(id); order.setName("手机订单"); List<OrderItem> orderItems = new ArrayList<OrderItem>(); order.setOrderItems(orderItems); OrderItem orderItem1 = new OrderItem(); orderItem1.setId(1L); orderItem1.setProduct("iPhone 4"); orderItem1.setPrice(5000); orderItems.add(orderItem1); OrderItem orderItem2 = new OrderItem(); orderItem2.setId(2L); orderItem2.setProduct("Nokia N97"); orderItem2.setPrice(4000); orderItems.add(orderItem2); return order; } /** * * @param order should be updated * @param deletedItemIndexes orderItem indexes should be deleted * 简单的在控制台打印出结果,如果存入到数据库,可以根据orderItem id * 是否为null,进行更新或者保存。 */ public void update(Order order, List<Integer> deletedItemIndexes) { if(deletedItemIndexes != null){ for(int i = deletedItemIndexes.size() - 1; i >= 0; i--){ order.getOrderItems().remove(deletedItemIndexes.get(i).intValue()); } } StringBuilder sb = new StringBuilder(); sb.append("Order Id: ").append(order.getId()).append("\tName: ").append(order.getName()).append("\n"); List<OrderItem> items = order.getOrderItems(); for (OrderItem orderItem : items) { sb.append("Item Id: ").append(orderItem.getId()).append("\tName: ").append(orderItem.getProduct()).append("\tprice: ").append(orderItem.getPrice()).append("\n"); } System.out.println(sb.toString()); } }
BTW:Java的自动拆装箱要注意,特别是List#remove有两个重载的方法,
remove(Object) remove(int),这个必须手工拆箱。
评论
3 楼
fuliang
2011-02-27
junnyfan 写道
我想同问,如果成员属性是Set如何绑定呢?
好像不可以,绑定的需要能够按照下标访问的,而Set本身不能确保有序,所以不能下标访问。最好在VO中使用List绑定,然后和PO的Set转换一下。
2 楼
junnyfan
2011-02-27
我想同问,如果成员属性是Set如何绑定呢?
1 楼
蓝之月
2011-01-20
如果对象成员为SET,如何绑定呢?
发表评论
-
自定义Jackson Json的Serializer
2011-08-05 18:52 16153转载请标明出处: http://fuliang.iteye.c ... -
Spring MVC form data binding and ajax form
2011-04-12 23:26 7342Model和View绑定是虽然不是MVC模式的标配,但是Mod ... -
使用Spring MVC HandlerExceptionResolver处理异常
2011-03-08 23:31 72400转载请标明出处:http://fuliang.iteye.co ... -
使用HandlerInterceptor实现简单的授权
2010-11-04 19:37 24072实现拦截器接口HandlerInterceptor或者Hand ... -
BeanPropertyRowMapper
2010-10-07 22:19 8826spring 2.5+提供了BeanPropertyRowMa ... -
使用Struts2+Hibernate+Spring写了一个RSS Reader
2008-04-06 22:11 4834一个简单的RSS Reader其实很好写,或许根本不需要使用S ... -
体验一下Spring2.5 Annotation-based-configration
2008-03-17 21:22 4158Spring2.5 Annotation-based-conf ... -
Dependency injection都有人质疑??
2008-01-12 12:46 1791Proffitt认为DI流行的唯一 ... -
Open Session in View
2007-12-08 23:57 3848我们在使用Hibernate的lazy load来优化 ... -
使用Struts2+Spring+Hibernate+sitemesh做的一个在线音乐站点
2007-11-03 16:21 9966前段时间用用Struts2+Spring+Hibernate+ ...
相关推荐
Acronis Backup:Acronis备份策略设计原理.docx
phpEasyVCS-2.0.zip
2023-04-06-项目笔记-第三百五十一阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.349局变量的作用域_349- 2024-12-18
CSDN Matlab研究室上传的资料均有对应的仿真结果图,仿真结果图均是完整代码运行得出,完整代码亲测可用,适合小白; 1、完整的代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
用户管理: 能够完成用户基本信息录入的注册和用户基本信息的修改。 管理员管理: 能够完成管理员对网站的商品信息管理(商品添加、商品审查)、会员管理(会员审查)、网站信息管理(新闻添加、修改删除、公告设置),以及常规设置(广告添加,友情链接)的功能。 搜索功能: 能过电子商品的名称进行搜索。 查询功能: 能够通过查看购物车对所选商品进行确定、挑选。 环境说明: 开发语言:Java,jsp JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea 部署容器:tomcat
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2540/CC2541上运行,如果是其他型号芯片,请自行调整。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。
CSDN Matlab研究室上传的资料均有对应的仿真结果图,仿真结果图均是完整代码运行得出,完整代码亲测可用,适合小白; 1、完整的代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
CSDN Matlab研究室上传的资料均有对应的仿真结果图,仿真结果图均是完整代码运行得出,完整代码亲测可用,适合小白; 1、完整的代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
IO总结总结总结总结总结
系统能够对客户信息管理、订单管理、商品信息管理、供应商管理、库存管理,系统用户管理等信息提供存储、更新、查询、统计的功能。 环境说明: 开发语言:Java,jsp JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea 部署容器:tomcat
前台模块: 站内新闻:发布与视频教学相关的新闻和动态。 视频学习:提供视频教学内容,供用户学习。 在线留言:用户可以在线提交留言或反馈。 用户注册:允许新用户注册成为网站的会员。 在线论坛:提供一个在线讨论的平台。 资料下载:提供学习资料或其他相关文件的下载服务。 管理员模块: 系统用户管理:管理系统用户的账户信息。 注册用户管理:管理注册用户的资料和信息。 教师信息管理:管理教师的资料和信息。 站内新闻管理:管理网站新闻内容的发布和更新。 课程信息:管理课程的相关信息。 资料下载管理:管理可供下载的资料。 论坛管理:管理在线论坛的内容和用户互动。 注册用户模块: 教师资料修改:教师可以修改自己的个人信息。 作业发布管理:用户可以发布作业或相关任务。 在线资料下载:注册用户可以下载在线资料。 学生资料管理:学生可以管理自己的资料。 学生下载作业:学生可以下载教师发布的作业。 环境说明: 开发语言:Java,jsp JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea 部署容器:tomcat
汉普美的ERP简介、实施、应用.ppt
深圳混泥土搅拌站资金、现金、费用管理规定
98年的telnetBBS软件,配合worldgroup server使用(16位),是瀛海威时空客户端的英文原版。
5aaaaaaaaaaaaaaaaaaaaaa
这个项目是一个基础的Go微服务框架,适合作为微服务架构的学习项目。希望这个项目能帮助你入门Go语言的微服务开发!
此为报告样本,完整报告的框架结构
传送带中大块煤识别检测数据集,使用coco json格式对792张图片标注,标注图片和标注信息可参考博文:https://backend.blog.csdn.net/article/details/144513245
此工具能快速有效的修复系统缺失的DLL和DirectX文件
计算机组成原理课程设计(模型机).doc