您的位置:首页 > 编程语言 > Java开发

【java】itoo项目实战之SpringMVC_@ModelAttribute解决部分更新问题

2015-02-22 18:28 429 查看

需求:

要求修改数据库中的某条记录的部分,部分值不能给修改.例如:数据库表有3个字段,有1个字段不能被修改,而更新的时候,表单提交的只有两个参数,实体中只有两个属性被赋值,其中一个属性是null值.用平常的update更新,会有一个字段被置空.一般的更新方法如下图所示:



传统解决方案:

一.隐藏域但是隐藏域有两个问题,问题一:如果是比较敏感的字段,不能放隐藏域,另一个问题就是字段较多的情况,使用隐藏域比较麻烦.
二.更新之前,先做查询操作.把表单未提交的值通过查询获取.这样的方法也比较麻烦.

高质量解决方案:即使用SpringMVC注解@ModelAttribute

对象从数据库中获取的.如图所示:



出现这样的原因是对象是new出来的,建立一个新的对象,这个对象之是空的.
具体代码:
Hander:
/**
	 *  有 @ModelAttribute 标记的方法, 会在每个目标方法执行之前被 SpringMVC 调用! 
	 */
	@ModelAttribute
	public void getUser(@RequestParam(value="id",required=false) Integer id, 
			Map<String, Object> map){
		System.out.println("modelAttribute method");
		if(id != null){
			//模拟从数据库中获取对象
			User user = new User(1, "Tom", "123456", "tom@atguigu.com", 12);
			System.out.println("从数据库中获取一个对象: " + user);
			
			map.put("user", user);
		}
	}
@RequestMapping("/testModelAttribute")
	public String testModelAttribute(User user){
		System.out.println("修改: " + user);
		return SUCCESS;
	}

View:
<!--  
		模拟修改操作
		1. 原始数据为: 1, Tom, 123456,tom@atguigu.com,12
		2. 密码不能被修改.
		3. 表单回显, 模拟操作直接在表单填写对应的属性值
	-->
	<form action="springmvc/testModelAttribute" method="Post">
		<input type="hidden" name="id" value="1"/>
		username: <input type="text" name="username" value="Tom"/>
		<br>
		email: <input type="text" name="email" value="tom@atguigu.com"/>
		<br>
		age: <input type="text" name="age" value="12"/>
		<br>
		<input type="submit" value="Submit"/>
	</form>

执行结果:



运行流程:

1.执行
@ModelAttribute注解修饰的方法:从数据库中取出对象,把对象放入到了
Map中.键为: user
2. SpringMVC从
Map中取出 User对象,并把表单的请求参数赋给该User对象的对应属性.
3. SpringMVC把上述对象传入目标方法的参数.
注意:在
@ModelAttribute修饰的方法中,放入到 Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致!

下面在dug的模式下,通过分析源代码来分析流程:
1.调用
@ModelAttribute注解修饰的方法.实际上把@ModelAttribute方法中
Map中的数据放在了implicitModel中.
2.解析请求处理器的目标参数,实际上该目标参数来自于WebDataBinder对象的
target属性
1).创建
WebDataBinder对象:
①.确定
objectName属性:若传入的 attrName属性值为"",则
objectName为类名第一个字母小写.
注意:attrName.
若目标方法的 POJO属性使用了@ModelAttribute来修饰,则
attrName值即@ModelAttribute
的 value属性值

②.确定
target属性:
>在
implicitModel 中查找 attrName对应的属性值.若存在,
ok
>若不存在:则验证当前
Handler是否使用了@SessionAttributes进行修饰,若使用了,则尝试从
Session中 获取 attrName所对应的属性值.若
session中没有对应的属性值,则抛出了异常.

>若
Handler 没有使用@SessionAttributes进行修饰,或@SessionAttributes中没有使用
value值指定的 key和 attrName相匹配,则通过反射创建了
POJO对象

2). SpringMVC把表单的请求参数赋给了
WebDataBinder的 target对应的属性.
3). SpringMVC会把
WebDataBinder的 attrName和 target给到
implicitModel.近而传到 request
域对象中.
4).把
WebDataBinder的 target作为参数传递给目标方法的入参.

pojo类型的参数:

(一)如何确定
SpringMVC确定目标方法 POJO类型入参的过程
1.确定一个
key:
1).若目标方法的
POJO类型的参数木有使用 @ModelAttribute作为修饰,则
key为 POJO类名第一个字母的小写
2).若使用了
@ModelAttribute来修饰,则 key为@ModelAttribute注解的
value属性值.
2.在
implicitModel中查找 key对应的对象,若存在,则作为入参传入
1).若在
@ModelAttribute标记的方法中在 Map中保存过,且
key和 1确定的 key一致,则会获取到.
3.若
implicitModel中不存在 key对应的对象,则检查当前的
Handler是否使用@SessionAttributes注解修饰,
若使用了该注解,且
@SessionAttributes注解的 value属性值中包含了 key,则会从HttpSession中来获取
key所
对应的 value值,若存在则直接传入到目标方法的入参中.若不存在则将抛出异常.
4.
若 Handler没有标识 @SessionAttributes注解或
@SessionAttributes注解的 value值中不包含 key,则会通过反射来创建
POJO类型的参数,传入为目标方法的参数
5. SpringMVC
会把 key和 POJO类型的对象保存到implicitModel中,进而会保存到
request中.

(二)修饰入差
2. @ModelAttribute
注解也可以来修饰目标方法 POJO类型的入参,其
value属性值有如下的作用:
1). SpringMVC会使用
value属性值在 implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参中.
2). SpringMVC会一
value为 key, POJO类型的对象为 value,存入到
request中.

巧妙的使用@ModelAttribute属性解决更新有的值被置空的问题.学会站在巨人的肩膀上,提高自己的代码质量.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐