一:说明

1.使用场景

  在下面的场景中:

  使用new对象时,最后的效果是两个被赋值了,但是还有一个值是空值的,这个不符合只更新两个值,另一个值不变的情况。

  

  正确的做法:

  三个值得数据不是new出来的,而是从数据库中获取。

  这种做法适合于本文的注解。

  

2.注解的知识点

  有@ModelAttribute标记的方法,会在每个目标方法执行之前被SpringMVC调用。

二:程序

1.bean对象--Person

 package com.spring.bean;

 public class Person {
private Integer id;
private String username;
private String password;
private String email;
private int age;
private Address address; public Person() {}
public Person(String username, String password, String email, int agem,Address address) {
super();
this.username = username;
this.password = password;
this.email = email;
this.age = age;
this.address = address;
}
//不带address的构造函数
public Person(String username, String password, String email, int age) {
super();
this.username = username;
this.password = password;
this.email = email;
this.age = age;
}
//带id的构造函数
public Person(Integer id,String username, String password, String email, int age) {
super();
this.id=id;
this.username = username;
this.password = password;
this.email = email;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Person [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", age="
+ age + "]";
} }

2.insex

 <%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<!--
原始数据:1,tom,123456,tom@123.com,12
要求:数据不能改变
表单回显 id username password email age
-->
<form action="helloworld9" method="post">
<input type="hidden" name="id" value="1"/><br/><br>
username:<input type="text" name="username" value="tom"/><br/><br>
email:<input type="text" name="email" value="tom@123.com"/><br/><br>
age:<input type="text" name="age" value="12"/><br/><br>
<input type="submit" value="Submit">
</form>
</body>
</html>

3.controller

 package com.spring.it;

 import java.util.Map;

 import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import com.spring.bean.Person; @Controller
public class ModelAttributeControl { /**
* 这是表单的post请求
*/
@RequestMapping("/helloworld9")
public String hello(Person person) {
System.out.println("修改:"+person);
return "success";
} /**
* 模拟从数据库中取得一个Person对象
*/
@ModelAttribute
public void getPerson(@RequestParam(value="id",required=false) Integer id,Map<String,Object> map) {
if(id!=null) {
//原始数据:1,tom,123456,tom@123.com,12
Person person=new Person(1, "tom", "123456", "tom@123.com", 12);
System.out.println("从数据库中获取一个数据:"+person);
map.put("person", person);
}
}
}

4.效果

  

  其他的数据保持不变,主要看的数据是psaaword:

  

三:会导致的异常

1.异常

  通过源码的分析:

  在确定targer时,在implicitModel中查找attrName对象的属性值,若存在,则ok

  如果不存在,则验证当前是否使用了@SessionAttributes进行修饰,进行了修饰,则尝试从Session中获取值,若session中没有attrName对应的属性值,则跑出异常。

  若没有使用@SessionAttributes进行修饰,或者@SessionAttributes没有使用键与attrName匹配,则通过反射创建POJO对象。

2.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 中.

四:ModelAttribute注解修饰POJO类型的入参

1.程序实例

   @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("abc", user);
}
} @RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("abc") User user){
System.out.println("修改: " + user);
return SUCCESS;
}

2.解释

  上面的put中放入的key是abc,所以需要在使用user的地方进行ModelAttribute注解。

  如果是默认的情况下,就是说不使用注解,就需要使用默认的key,将第一个字母小写后的类名。

011 处理模型数据时@ModelAttribute的使用的更多相关文章

  1. Spring MVC 处理模型数据(@ModelAttribute)

    SpringMVC中的模型数据是非常重要的,因为MVC中的控制(C)请求处理业务逻辑来生成数据模型(M),而视图(V)就是为了渲染数据模型的数据. 直白来讲,上面这句话的意思就是:当有一个查询的请求, ...

  2. SpringMVC(十二):SpringMVC 处理输出模型数据之@ModelAttribute

    Spring MVC提供了以下几种途径输出模型数据:1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据:2)Map及Model:处理方法入参 ...

  3. 数据传递-------@ModelAttribute

    package com.wh.handler; /** * @ModelAttribute绑定请求参数到命令对象 * @ModelAttribute一个具有如下三个作用: * * ①绑定请求参数到命令 ...

  4. SpringMvc:处理模型数据

    SpringMvc提供了以下途径输出模型数据: -ModelAndView:处理方法返回值类型为ModelAndView,方法体即可通过该对象添加模型数据 -Map或Model:入参为org.spri ...

  5. 5、处理模型数据ModelAndView、Map、Model以及@SessionAttributes注解

    Spring MVC提供了以下几种途径输出模型数据 —— ModelAndView: 处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据.数据会添加到request域中. ...

  6. springmvc学习(五)——处理模型数据

    Spring MVC 提供了以下几种途径输出模型数据: ModelAndView: 处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据Map 及 Model: 入参 ...

  7. springMVC(6)---处理模型数据

    springMVC(6)---处理模型数据 之前一篇博客,写个怎么获取前段数据:springMVC(2)---获取前段数据,这篇文章写怎么从后端往前端传入数据. 模型数据类型             ...

  8. SpringMVC(十一):SpringMVC 处理输出模型数据之SessionAttributes

    Spring MVC提供了以下几种途径输出模型数据:1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据:2)Map及Model:处理方法入参 ...

  9. SpringMVC(十):SpringMVC 处理输出模型数据之Map及Model

    Spring MVC提供了以下几种途径输出模型数据: 1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据: 2)Map及Model:处理方法 ...

随机推荐

  1. 20155337 2016-2017-2 《Java程序设计》第七周学习总结

    20155337 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 •认识时间与日期 •格林威治标准时间:简称GMT时间,参考格林威治皇家天文台的标准太阳时间. ...

  2. Java EE之分页器设计

    由于数据库实训的课程设计,在做项目过程中,需要使项目更加规范的结构和各层间责任分离.无疑地,分页器是其中之一. 1. 本文仅陈述分页器如何实现,关于分页器的其他概念,请自行搜索其他网络资源. 2. 关 ...

  3. Spring源码解读

    beanfactory https://www.cnblogs.com/lspz/p/6244948.html requestmapping https://blog.csdn.net/u012557 ...

  4. geeksforgeeks-Array-Rotation and deletion

      As usual Babul is again back with his problem and now with numbers. He thought of an array of numb ...

  5. ubuntu 14.04 安装 eclipse

    在安装 eclipse 之前必须先安装 jdk 1. 卸载默认的 jdk,以防安装出错 sudo apt-get purge openjdk* 2. 安装 jdk1.8.0_111 下载jdk1.8. ...

  6. f-GAN

    学习总结于国立台湾大学 :李宏毅老师 f-GAN: Training Generative Neural Samplers using Variational Divergence Minimizat ...

  7. 【Android开发】之Fragment与Acitvity通信

    上一篇我们讲到与Fragment有关的常用函数,既然Fragment被称为是“小Activity”,现在我们来讲一下Fragment如何与Acitivity通信.如果上一篇还有不懂得,可以再看一下.传 ...

  8. 容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?【转】

    网易企业服务2017-10-13 无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker?什么时候用虚拟机?如果使用容器,应该使用哪个容器平台? 显而易见,我不会直接给大家一 ...

  9. OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据

    由于数据采集站基本都安装在野外或者楼顶,安装位置以及震动对检测数据的准确性有一定影响.所以想要有一个位置状态数据,正好发现麒麟作上有ADXL345,这样一个数字输出的加速度传感器.如图中红框所示: 1 ...

  10. 无法下载apk等格式的文件的解决方案---ASP .NET Core 2.0 MVC 发布到IIS上以后无法下载apk等格式的文件的解决方案

    ASP .NET Core MVC 发布到  IIS 上以后 无法下载apk等格式的文件 使用.NET Core MVC创建了一个站点,其他文件可以下载,但是后来又需求,就把手机端的apk合适的文件上 ...