深入SpringMVC-MoelAttribute

ModelAttribute

@ModelAttribute注解用于将请求的参数绑定到Model对象中,方便在前台回显

  • 在方法定义上使用@ModelAttribute注解:SpringMVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribue的方法
  • 在方法入参前使用@ModelAttribute注解
@ModelAttribute注解一个方法
@ModelAttribute("student")
public Student getStudent() {
	Student student = new Student("Reyco",21);
	return student;
}
  • 如果方法返回pojo对象,那么可以不用在@ModelAttribute中加上value属性,其值就是返回类型的首字母小写,即Student–>student
  • 如果方法没有返回值,那么可以在方法形参中加上一个Model类型,在方法体内执行addAttribute
  • 如果方法返回普通类型,那么可以在注解里面加上value属性,指定model中的key值

在调用控制器处理方法前如果有方法使用了@ModelAttribute注解,那么每个请求都会先请求这个方法,然后再调用控制器处理方法,假设请求A方法,则会先请求标注了@ModelAttribute的getStudent()方法,执行此方法会将student以(“student”,student)的形式添加到Model中,然后再执行A方法

@ModelAttribute注解方法的形参

在控制器的处理器方法参数上标注@ModelAttribute可以访问模型中的属性,如果不存在这个模型,则会自动将其实例化,产生一个新的模型,如果方法参数为pojo类在不是有@ModelAttribute时,默认在Model中查找pojo类首字母小写对象并传入

@RequestMapping("/test/sessionAttribute")
public String ModelTest(Map<String,Object> map,@ModelAttribute("student")Student student,Integer id){
	map.put("time",new Date());
	student.setAge(25);
	map.put("id",id);
	return SUCCESS;
}
  • SpringMVC会自动将pojo类型添加到Model中,key为该pojo的类名首字母小写,即使没有@ModelAttribute,仍然会将student写到Model中,类似map.put(“student”,student),如果想要改变key值,就必须使用@ModelAttribute(value=key)
  • 对于普通类型,SpirngMVC并不会自动注入到Model中,必须收到编写map.put(),栗子中id为Integer为普通类型,若想要注入Model中,就必须使用@ModelAttribute(value=key),或者在方法体内使用map.put(“xxx”,id)
@ModelAttribute和@RequestMapping方法作用于同一个方法
@RequestMapping("/login")
 @ModelAttribute("loginname")
  public String login(){
      return "admin";
  }
  • 当使用@RequestMapping和@ModelAtribute一起注解一个方法的时候,方法的返回值是会将加入到Model中的
  • 视图名应该是@RequestMapping的value的值,这里就是login
  • 请求的时候也是按照@RequestMapping的value进行请求
ModelAttribute原理剖析

@ModelAttribute修饰方法

  1. 调用@ModelAttribute注解修饰的方法,实际上把标注了@ModelAttribute方法中Map的数据放在了implicitModel中
  2. 解析请求处理器方法非@ModelAttribute修饰的方法)的目标参数,实际上该目标参数来自WebDataBinder对象的target属性
    1. 创建WebDataBinder对象:
      1. 确定objectName属性:若传入的attrName属性值为“”,则objectName为类名第一个字母小写注意:若目标方法的POJO属性使用了@ModelAttribute进行修饰,则attrName值即为@ModelAttribute设置的属性值
      2. 确定target属性:在implicitModel中查找attrName对于的属性值,若存在,ok;若不存在:则验证当前Handler是否使用了@SessionAttributes进行修饰,若使用了,则尝试从Session中获取attrName所对应的属性值,若Session中没有对于的属性值(抛出异常的情况是:@SessionAttributes设置了和attrName对应的key,但是这个key没有value),则抛出异常;若Handler没有使用@SessionAttributes进行修饰或@SessionAttributes中找不到和attrName相匹配的key,则通过反射创建POJO对象
    2. SpringMVC将表单的请求参数赋给了WebDataBinder中的target对应的属性
    3. SpringMVC将WebDataBinder的attrName和target给到implicitModel
    4. 将WebDataBinder的target作为参数传递给目标方法的入参

@ModelAttribute修饰POJO参数

  1. SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则直接传入到目标方法的入参中
  2. SpringMVC将@ModelAttribute的value作为key,POJO类型的对象作为value,存入到request域中
@SessionAttribute和@ModelAttributes引发异常

当使用@ModelAttribute注解时,会取@ModelAttribute的value值,若@ModelAttribute的value值是空串(即没有配置@ModelAttribute的value属性),则会将当前用@ModelAttribute修饰的方法的Bean参数或直接用@ModelAttribute修饰的Bean 的首字母小写Bean的名字作为attrName.

接下来会判断,如果request(Map)的键中包含了attrName,则取键值为attrName的值赋给Bean,若没有包含,会判断当前Handler是否使用了@SessionAttribute。若使用了则会判断@SessionAttribute的value或names中是否包含了attrName,若有,则将@SessionAttribute名为attrName的值作为attrName的值,若@SessionAttribute的values或names中包含但是没有相应的值,则会抛出 异常。若request(Map)和@SessionAttribute都不包含arrtName则利用反射新创建一个attrName的Bean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值