【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属性解决更新有的值被置空的问题.学会站在巨人的肩膀上,提高自己的代码质量.
相关文章推荐
- SpringMVC_@ModelAttribute解决部分更新问题!!!
- 解决Maven项目更新总出现的Dynamic Web Module 3.0 requires Java 1.5 or newer问题.
- 【java】itoo项目实战促学之SpringMVC注解_@RequestMapping
- 【java】itoo项目实战之常见问题三
- Connector 作为一个Java项目解决的问题
- Android项目导入出现The type java.lang.Object cannot be resolved.问题解决办法!!
- 从SVN上更新项目后,MyEclipse不能自动编译问题解决
- java_javadoc 生成项目文档(设置编码解决中文乱码问题)
- java项目 java web项目数据库乱码问题的解决办法
- linq更新部分数据时遇到的问题及解决办法
- 【转】使用JRockit作为工具检测并解决JAVA内存泄漏问题的一次实战
- 解决maven web项目倒入eclipse不出现Maven Dependencies 和 Java System Library的问题
- 解决IIS出现包含空格的项目的文件/路径部分需要用括号括起来的问题
- 如何解决在java开发中java代码和jsp页面中出现路径因为项目名称的变化(也就是应用名)的问题?
- Android SDK更新后 ADT R17 E/AndroidRuntime : java.lang.NoClassDefFoundError问题的解决
- 使用maven构建项目java.nio.BufferOverflowException问题的解决
- 如何解决java的web项目error-page不显示的问题
- android 开发中遇到的错误及解决方式(更新R.java文件不能自动更新问题)
- 移植java web 项目到go语言要解决的一系列问题
- 使用JRockit作为工具检测并解决JAVA内存泄漏问题的一次实战.doc