011 处理模型数据时@ModelAttribute的使用

一:说明

1.使用场景

  在下面的场景中:

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

  

  正确的做法:

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

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

  

 

2.注解的知识点

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

 

二:程序

1.bean对象--Person

 1 package com.spring.bean;
 2 
 3 public class Person {
 4     private Integer id;
 5     private String username;
 6     private String password;
 7     private String email;
 8     private int age;
 9     private Address address;
10     
11     public Person() {}
12     public Person(String username, String password, String email, int agem,Address address) {
13         super();
14         this.username = username;
15         this.password = password;
16         this.email = email;
17         this.age = age;
18         this.address = address;
19     }
20     //不带address的构造函数
21     public Person(String username, String password, String email, int age) {
22         super();
23         this.username = username;
24         this.password = password;
25         this.email = email;
26         this.age = age;
27     }
28     //带id的构造函数
29     public Person(Integer id,String username, String password, String email, int age) {
30         super();
31         this.id=id;
32         this.username = username;
33         this.password = password;
34         this.email = email;
35         this.age = age;
36     }
37     public String getUsername() {
38         return username;
39     }
40     public void setUsername(String username) {
41         this.username = username;
42     }
43     public String getPassword() {
44         return password;
45     }
46     public void setPassword(String password) {
47         this.password = password;
48     }
49     public String getEmail() {
50         return email;
51     }
52     public void setEmail(String email) {
53         this.email = email;
54     }
55     public int getAge() {
56         return age;
57     }
58     public void setAge(int age) {
59         this.age = age;
60     }
61     public Address getAddress() {
62         return address;
63     }
64     public void setAddress(Address address) {
65         this.address = address;
66     }
67     public Integer getId() {
68         return id;
69     }
70     public void setId(Integer id) {
71         this.id = id;
72     }
73     @Override
74     public String toString() {
75         return "Person [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", age="
76                 + age + "]";
77     }
78     
79     
80 }

 

2.insex

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

 

3.controller

 1 package com.spring.it;
 2 
 3 import java.util.Map;
 4 
 5 import org.springframework.stereotype.Controller;
 6 import org.springframework.web.bind.annotation.ModelAttribute;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.RequestParam;
 9 
10 import com.spring.bean.Person;
11 
12 @Controller
13 public class ModelAttributeControl {
14     
15     /**
16      * 这是表单的post请求
17      */
18     @RequestMapping("/helloworld9")
19     public String hello(Person person) {
20         System.out.println("修改:"+person);
21         return "success";
22     }
23     
24     /**
25      * 模拟从数据库中取得一个Person对象
26      */
27     @ModelAttribute
28     public void getPerson(@RequestParam(value="id",required=false) Integer id,Map<String,Object> map) {
29         if(id!=null) {
30             //原始数据:1,tom,123456,tom@123.com,12
31             Person person=new Person(1, "tom", "123456", "tom@123.com", 12);
32             System.out.println("从数据库中获取一个数据:"+person);
33             map.put("person", person);
34         }
35     }
36 }

 

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.程序实例

 1   @ModelAttribute
 2     public void getUser(@RequestParam(value="id",required=false) Integer id, 
 3             Map<String, Object> map){
 4         System.out.println("modelAttribute method");
 5         if(id != null){
 6             //模拟从数据库中获取对象
 7             User user = new User(1, "Tom", "123456", "tom@atguigu.com", 12);
 8             System.out.println("从数据库中获取一个对象: " + user);
 9             
10             map.put("abc", user);
11         }
12     }
13     
14     @RequestMapping("/testModelAttribute")
15     public String testModelAttribute(@ModelAttribute("abc") User user){
16         System.out.println("修改: " + user);
17         return SUCCESS;
18     }

 

2.解释

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

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

 

转载于:https://www.cnblogs.com/juncaoit/p/8460119.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的体育馆管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本体育馆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此体育馆管理系统利用当下成熟完善的SpringBoot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理收货地址管理、购物车管理、场地管理、场地订单管理、字典管理、赛事管理、赛事收藏管理、赛事评价管理、赛事订单管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。体育馆管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同,也实现了数据信息的整体化,规范化与自动化。 关键词:体育馆管理系统;SpringBoot框架;Mysql;自动化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值