SpringMVC---处理模型数据

ModuleAndView

在这里插入图片描述

  • 注意:ModelAndView的类型为:org.springframework.web.servlet.ModelAndView;
  • 示例使用ModuleAndView处理模型数据
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
    String viewName = SUCCESS;
    ModelAndView modelAndView = new ModelAndView(viewName);
    modelAndView.addObject("info", "你好");

    return modelAndView;
}
  • 使用ModuleAndView实际上会将数据使用request.setAttribute()方法保存在请求域之中.因此可以在页面中使用EL表达式获取请求属性.
  • 跳转的页面
<body>
	<h1>${info}</h1>
</body>

在这里插入图片描述

在这里插入图片描述

Map处理模型数据

在这里插入图片描述

  • 示例:
    @RequestMapping("/testMap")
    public String testMap(Map<String,Object> map){
        map.put("time",new Date());
        map.put("tom","xiemaoshu");
        return SUCCESS;
    }

  • SpringMVC会将数据存储到 Request范围域之中,在页面中可以使用 EL表达式取出数据
<h1>${time}</h1>
<h1>${tom}</h1>
  • 执行效果

在这里插入图片描述

@SessionAttributes

在这里插入图片描述

  • @SessionAttribute注解使用示例
//将名称为"user"的属性添加到Session属性之中,也将String类型的属性添加到Session属性之中
@SessionAttributes(types = {User.class,String.class},value = {"user"})
@Controller
public class HelloWorld {

    @RequestMapping("/testSessionAttribute")
    public  String testSessionAttribute(Map<String,Object> map){
        User user = new User();
        user.setUid(11);
        user.setUname("xiemaoshu");
        user.setPassword("xiemaoshu20190309xms");
        map.put("user",user);
        map.put("time",new Date());
        return SUCCESS;
    }
  • 显示页面
<h1>${user}</h1>
<h1>${time}</h1>
  • 效果

在这里插入图片描述

@ModuleAttribute注解

遇到的问题?

  • 如果此时要进行对数据库中的一个数据进行修改操作,但是要求:某一个字段的内容不允许被修改.例如:修改一个用户的数据"User",用户数据中的创建时间与密码信息是不允许被修改的.如果从表单中直接收要修改的数据,那么在操作方法中往往需要提供一个User类实例化对象,那么这个User类实例化对象中,"创建时间"和"密码"字段只能够是"null"空,如何能够放置出现null的情况?

实现的思路有两种:

  1. 由表单填入修改数据,但是不提供"创建时间"和"密码"的修改操作,将用户的创建时间和密码信息由隐藏域保存起来,接着再调用方法中new一个实例化对象,将修改数据保存到新的实例化对象之中.
    - 这样做有一个缺点就是:重要的信息不适合放在隐藏域中,况且,如果不能够修改的字段比较多的话,需要设置多个隐藏域.

在这里插入图片描述

  1. 先从数据库中读取出要修改的用户信息,而后只提供要修改的数据操作

在这里插入图片描述

使用@ModuleAttribute解决

  • 模拟一个数据修改操作
  1. 修改页面表单
<body>

<%--
    模拟一个数据修改操作
    原始数据为:
    uid=1
    password=12345
    uname=xiemaoshu
--%>
<form method="post" action="testModelAttribute">
    <div>
        用户id:<input type="text" name="uid" id="uid" value="1"/>
    </div>

    <div>
        用户名称:<input type="text" name="uname" id="uname" value="xiemaoshu"/>
    </div>
    <div>
        <input type="submit" value="提交"/>
    </div>
</form>

</body>
  • 进行修改操作的方法
   @ModelAttribute//SpringMVC在执行映射请求方法之前,会先调用带有@ModelAttribute 注解的方法
    public void getUser(@RequestParam(value = "uid",required = false) Integer uid,Map<String,Object> map){

        //模拟从数据库中获取用户数据
        User user =new User();
        user.setUid(uid);
        user.setUname("xiemaoshu");
        user.setPassword("12345");
        map.put("user",user);//将user数据保存到request请求域之中
        
        System.out.println("获取uid = "+uid+" 的用户数据"+user);
    }

    @RequestMapping("/testModelAttribute")
    public String testModelAttribute(User user){
        System.out.println("执行修改操作:"+user);
        return SUCCESS;
    }
  • 测试结果

在这里插入图片描述

  • 后台输出
  • 可以发现password不为null,这是因为在执行请求方法前,会先执行"@ModelAttribute"注解的方法

在这里插入图片描述

@ModelAttribute运行原理

  • 运行流程:

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

@ModelAttribute注解之源码分析

  1. 调用@ModelAttribute注解修饰的方法,实际上把@ModelAttribute方法中Map中的数据放在了implicitModel中

  2. 解析请求处理器的目标参数,实际上该目标来自于WebDataBinder对象的target属性

  3. 创建WebDataBinder对象:

    1. 确定objectName属性:若传入的arrtName属性值为空字符串,则objctName为类名第一个字母小写.(=乳沟目标方法的POJO回信息使用了@ModelAttribute来修饰,则attrName值即为@ModelAttribute的value属性值==)
    2. 确定target属性:
      • 在implicitModel中查找attriName对应的属性值.
      • 若不存在:则验证当前的Hiddler是否使用了@SessionAttribute进行修饰,若使用了,则尝试从Session中获取arrtName所对应的属性值,若session中没有对应的属性值,则抛出异常.
      • 若Handler没有使用@SessionAttribute进行修饰,或@SessionAttributes中没有使用value值指定的key和attrName相匹配,则通过反射创建了POJO对象.
  4. SpringMVC把表单中请求参数赋给WebDataBinder的target属性.

  5. SpringMBC会把WebDataBinder的attrName和target给到implicitModel

  6. 把webDataBinder的target作为参数传递给目标方法的入参.

  • 在"@ModelAttribute"注解的方法中和请求的方法中打上断点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值