SpringMVC笔记三:处理模型数据

处理模型数据

Spring MVC 提供了以下几种途径输出模型数据:

1.1.ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据

    /*
     * 处理方法的返回值可以是ModelAndView类型,其中可包含视图和模型信息
     * SpringMVC会把ModelAndView的model中的数据放到request域对象
     */
    @RequestMapping("/ModelAndView")
    public ModelAndView testModelAndView() {
        ModelAndView modelAndView = new ModelAndView("hello");
        modelAndView.addObject("time",new Date());
        return modelAndView;
    }

如果想要在JSP页面上获取对应的值可以通过如下的方法:

    time now: ${requestScope.time}<br>
  • @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中

1.2.Handler 方法可以接受Map类型的参数

Map 及 Model: 入参为org.springframework.ui.Model、org.springframework.ui. ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。

Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。

/*
 * 目标方法可以添加Map类型(也可以是Model/ModelMap类型)
 */
 @RequestMapping("/testMap")
    public String  testMap(Map<String,Object> map) throws IOException {
        map.put("names", Arrays.asList("Tom","Lisa","Allen"));
        return "hello";
    }

jsp页面中添加:

names list: ${requestScope.names}

1.3. 控制类上的@SessionAttributes

该注解只能标识在类上面
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC 将在模型中对应的属性暂存到 HttpSession 中。

/*
 * @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,(value)
 * value={"user"}含义是把模型中属性为"user"的,(map中的键值)
 * 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types)
 * types指定的是map中的值类型符合就保存在session中
 * (requestScope一样含有这些模型属性)
 */
@SessionAttributes(value={"user"},types ={String.class})
@RequestMapping("/TestRequest")
@Controller
public class HelloWorld {
    @RequestMapping("/Session")
    public String testSessionAttribute(Map<String,Object> map){
        User user = new User("kaixin","123456",new Address("nanchang","AlongRiver"),19);
        map.put("user",user);
        map.put("school","hust");
        return "hello";
    }
}
 request user:${requestScope.user}<br>
 session user:${sessionScope.user}<br>
 request school:${requestScope.school}<br>
 session school:${sessionScope.school}<br>

localhost:8080/SpringMVC01/TestRequest/Session上显示

request user:User{username='kaixin', password='123456', address=Address{city='nanchang', street='AlongRiver'}, age=19}
session user:User{username='kaixin', password='123456', address=Address{city='nanchang', street='AlongRiver'}, age=19}
request school:hust
session school:hust

注:
传入数据到Map中时,一般情况下对于键的名称没有做特别的要求,但如果是在@ModelAttribute中,因为map的数据是作为参数传给处理器方法的,所以要求键的名称对应bean类的首字母小写。

1.4.@ModelAttribute

参考
https://blog.csdn.net/xiangwanpeng/article/details/53069533

讨论@ModelAttribute的作用及工作流程。即:有一个Graduate类,有id、studentname、email、password四个属性。现在要完成一个更新操作,但是其中有一项属性不能被修改,例如id,那么只能修改三项属性,password、studentname和email,所以从form表单传递的信息就只能有这三项,我们是通过@ModelAttribute注解标记方法来实现的:(其中数据库相关的操作仅采用模拟的方式)

1.4.1 注:

若目标方法的 POJO 类型的参数没有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写;
若目标方法的 POJO 类型的参数使用了@ModelAttribute 来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值。

1.4.2
SpringMVC确定目标方法POJO入参的全过程

在这个例子中,SpringMVC通过映射请求调用目标处理方法testModelAttribute方法之前,做了下面三件事情:
  第1步: 执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象,把对象放入到了 Graduate中,键为:undergraduate。(见1.4.1)
  第2步: SpringMVC 从 Map 中取出 Graduate 对象 graduate1, 并把表单的请求参数赋给 graduate1的对应属性。
  第3步: SpringMVC 把上述对象作为参数传入目标方法testModelAttribute(Graduate id1)。

     /*
     * 源码分析:
     * 1.调用@ModelAttribute修饰的方法,实际上@ModelAttribute修饰的方法中的Map的数据放到implicitModel
     * (这是一个BindingAwareModelMap类型的对象,BindingAwareModelMap类型实现了Map接口)中
     * 2.解析请求处理器的目标参数,实际上该目标参数来源于WebDataBinder的target属性
     *  1)创建WebDataBinder对象
     *      ①确定Attribute属性:(确定key)
     *      若传入的属性值为"",则ObjectName为类名首字母小写
     *      注:若目标方法的POJO属性使用了@ModelAttribute修饰,则ObjectName值即为
     *      @ModelAttribute的value值
     *      ②确定target属性:(确定value)
     *      Ⅰ 在implicitModel中查找attributeName对应的属性值.找到ok;
     *      Ⅱ 若 implicitModel 中不存在 key 对应的对象,
     *      则检查当前的控制器类是否被@SessionAttributes注解修饰 ,如果使用了@SessionAttributes注解修饰,
     *      且@SessionAttributes注解的value属性值中包含了key,则尝试从HttpSession中获取key所对应的value值,
     *      如果value值存在则获取到,若存在则直接传入到目标方法的入参中。
     *      如果value值不存在则抛出异常。
     *     如果没有使用@SessionAttributes注解修饰该控制器类,或者使用了,
     *      但是@SessionAttributes注解中的value值不包含key,
     *      则SpringMVC会通过反射来创建一个POJO类型的对象。
     *  2)SpringMVC将表单参数赋给WebDataBinder对象的target属性
     *  3)SpringMVC将WebDataBinder的Attribute 、target属性给implicitModel
     *  4)把target作为参数传给目标方法的入参
     */
    @ModelAttribute
    public void getStudentInfo(@RequestParam(value = "id",required = false)Integer id,
                    Map<String,Object> map){
        if(id!=null){
            //模拟从数据库中获取对象
            Graduate graduate1 =new Graduate("Tom","123456789",1,"hust@edu.cn");
            System.out.println("从数据库中获取一个对象");
            //把对象放入到map中
            map.put("undergraduate", graduate1);//map中的键和目标方法的入参类型的名首字母小写
        }
    }
    @RequestMapping("/testModelAttribute")
    //在传入目标对象前,SpringMVC会从Map中取出Graduate对象,并把表单请求参数赋给对应的属性值
    public String testModelAttribute(@ModelAttribute("undergraduate") Graduate id1){
        System.out.println("修改:"+id1);
        return "hello";
    }
}

源码分析有一丢丢复杂,总之就是到处找key,找完key找对应的value,可以没有key(也就没有value),但不可以有key没value(抛异常)。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值