Spring MVC 传递模型数据到视图中的方法总结

一般来说,有如下的4种方法来传递模型数据到视图中

1、ModelAndView

要求:处理方法返回值类型为 ModelAndView。在方法体中我们通过该ModelAndView对象添加模型数据。

2、Model/Map/ModelMap

要求:使用org.springframework.ui.Model、org.springframework.ui.ModelMap 或 Java.uti.Map 作为处理方法的入參时,当处理方法返回时,Map中的数据会自动添加到模型中,具体实例将在后面介绍。

3、@SessionAttributes

使用该注解来注解某个类,使得将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性。

4、@ModelAttribute

该注解即可注解在有返回值的方法上,无返回值的方法上,还可以注解在方法入参上,当入參标注该注解后, 入参的对象就会放到数据模型中,具体将在后面进行介绍。

下面将分别以例子的形式进行介绍。

ModelAndView

1、创建ModelAndView,并传入模型数据 

    @Controller
    public class HelloController {

        @RequestMapping(value = "/testModelAndView.do",method = RequestMethod.GET)
        public ModelAndView testModelAndView(){
            String viewName = "hello";//视图名
            ModelAndView modelAndView = new ModelAndView(viewName);

            modelAndView.addObject("time",new Date());
            modelAndView.addObject("name","ModelAndView");
            return modelAndView;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

该处理方法返回的是一个ModelAndView对象,且在方法体中添加了以“time”和“name”为key的数据。

2、编写JSP

编写名为:“hello.jsp”,内容如下:

    <html>
    <body>
    <h2>method:${requestScope.name}</h2>

    ${requestScope.time}<br>

    ${requestScope.get("time")}<br>

    ${time}
    </body>
    </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这样,在浏览器中输入:localhost:8080/testModelAndView.do ,即可看到如下的输出结果:

注意: 
requestScope.time,requestScope.time,{requestScope.get(“time”)},${time}这三种写法效果是一样的,在不同的书籍/博客中所看到的都是其中的一种。

2、Model/Map/ModelMap

Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。

如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,我们可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。

Model和Map使用上基本一样,具体实现代码如下图所示。

    @RequestMapping(value = "/testModel.do",method = RequestMethod.GET)
    public String testModel(Model model){
        model.addAttribute("time",new Date());
        model.addAttribute("name","Model");
        return "hello";
    }

    @RequestMapping(value = "/testMap.do",method = RequestMethod.GET)
    public String testMap(Map<String,Object> map){
        map.put("time",new Date());
        map.put("name","Map");
        return "hello";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

上面代码所对应的hello.jsp与上面ModelAndView的hello.jsp一样。

经测试验证是可以正常工作的。

3、@SessionAttributes

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

注意:@SessionAttributes这个注解只能放到类的上面

如下代码为:首先使用Map将模型数据存到模型对象中,然后在类定义处使用@SessionAttributes,拷贝到Session中

    @SessionAttributes({"name","time"})
    @Controller
    public class HelloController {

        @RequestMapping(value = "/testSessionAttribute.do",method = RequestMethod.GET)
        public String testSessionAttribute(Map<String,Object> map){
            map.put("time",new Date());
            map.put("name","SessionAttribute");
            return "sessionAttribute";
        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

sessionAttribute.jsp的内容如下:

    <html>
    <body>
    <h2>method:${requestScope.name}</h2>
    ${requestScope.time}<br>
    ${requestScope.get("time")}<br>
    ${time} <br>
    sessionScope.time:${sessionScope.time}
    </body>
    </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这样,在浏览器中输入:localhost:8080/testSessionAttribute.do ,即可看到如下的输出结果:

4、@ ModelAttribute

前面谈到SpringMVC在每次调用请求处理方法时,都会创建Model类型的一个隐含实例对象。如果准备使用此实例,则可以在方法中添加一个Model类型的输入参数。事实上,还可以使用在方法中添加@ModelAttribute注释类型来访问Model实例。

  可以用@ModelAttribute来注释方法参数:带有@ModelAttribute注解的方法会将其输入或创建的参数对象添加到Model对象中(若方法中没有显式添加)。

  可以用@ModelAttribute标注一个非请求的处理方法(有返回值,无返回值):被@ModelAttribute注释的方法会在此controller每个方法执行前被执行。 

4.1 @ ModelAttribute注解在有返回值的方法上

@ ModelAttribute注解在有返回值的方法上,则该返回值会被添加到模型对象中。

    @ModelAttribute
    public User addUser(User user){//
        user.setName("Model Attribute in Mehtod ,this method has return value");
        return user;

    }
    @RequestMapping(value = "/testModelAttributeInReturnValueMethod.do",method = RequestMethod.GET)
    public String testModelAttributeInReturnValueMethod(){
        return "modelAttributeInRVMethod";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

即使addUser方法的方法体中并没有显示的将模型数据添加到Model中,由于使用了@ModelAttribute注解,它会帮我们完成添加。

modelAttributeInRVMethod.jsp的内容如下:

    <html>
    <body>

    <h2>name:${user.name}</h2>

    </body>
    </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

测试结果如下:

还有一点需要说明的是:返回User对象,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称是user,因此,在如上的jsp文件中就可以使用user.name访@ModelAttribute(value="myUser"),jsp使user.name来访问,如果指定属性的名称,例如:@ModelAttribute(value="myUser"),则在jsp中就需要使用{myUser.name}来访问

看一个指定属性名称的例子:

     /**
     * 对象合并指定对象名称
     * */
    @RequestMapping(value = "/testModelAttribute4.do",method = RequestMethod.GET)
    public String testModelAttribute4(@ModelAttribute("myUser") User user ){
    //对模型对象中的对象user进行更改
        user.setAge(20);
        return "modelAttribute4";

    }
    @ModelAttribute(value = "myUser")//指定对象名称,并添加到模型对象中
    public User myUser(){
        User user = new User();
        user.setName("wojiushimogui");
        return user;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

相应的jsp文件内容如下:

    <html>
    <body>

    <h2>name:${myUser.name}</h2>
    <h2>name:${myUser.age}</h2>
    </body>
    </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

测试结果如下:

4.2 @ModelAttribute注解在void返回值的方法上

@ModelAttribute注解在void返回值的方法上,与注解在有返回值的方法上不同的时,需要显示的添加模型数据到Model对象中。

    /**
     * @ModelAttribute注解void返回值的方法
     * */
    @ModelAttribute
    public void addUser(User user,Model model){
        user.setName("Model Attribute in Mehtod ,this method  not return value");
        model.addAttribute("user",user);

    }
    @RequestMapping(value = "/testModelAttributeInNonReturnValueMethod.do",method = RequestMethod.GET)
    public String testModelAttributeInNonReturnValueMethod(){
        return "modelAttributeInNonRVMethod";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

modelAttributeInNonRVMethod.jsp的内容与modelAttributeInRVMethod.jsp的内容完全一样,这里不再贴出。

运行结果如下: 

有趣的是,如果在一个控制器HelloController.java文件中(如下所示),即存在@ModelAttribute注解在有返回的方法上,也注解在void返回值方法上,且模型中包括的模型数据名称一致,会出现什么结果呢??看如下的程序代码

    @Controller
    public class HelloController {
        /**
         * 将@ModelAttribute 注解在有返回值的方法上,
         * 
         * */
        @ModelAttribute
        public User addUser(User user){
            user.setName("Model Attribute in Mehtod ,this method has return value");
            return user;

        }
        /**
         * @ModelAttribute注释void返回值的方法
         * */
        @ModelAttribute
        public void addUser(User user,Model model){
            user.setName("Model Attribute in Mehtod ,this method  not return value");
            model.addAttribute("user",user);
        }
        @RequestMapping(value = "/testModelAttributeInReturnValueMethod.do",method = RequestMethod.GET)
        public String testModelAttributeInReturnValueMethod(){
            return "modelAttributeInRVMethod";
        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

运行结果为:

猜想可不可能与两个使用了@ModelAttribute前后位置有关系,交换位置测试了下,确实有关系。交换后的代码如下:

    @ModelAttribute
    public void addUser(User user,Model model){
        user.setName("Model Attribute in Mehtod ,this method  not return value");
        model.addAttribute("user",user);
    }
    @ModelAttribute
    public User addUser(User user){
        user.setName("Model Attribute in Mehtod ,this method has return value");
        return user;

    }

    @RequestMapping(value = "/testModelAttributeInReturnValueMethod.do",method = RequestMethod.GET)
    public String testModelAttributeInReturnValueMethod(){
        return "modelAttributeInRVMethod";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

测试结果如下:

小结,在实际项目中我们可能不会这么写,以上是纯属好奇测试了下,结论为:“谁靠前,谁做主”。

4.3 @ModelAttribute注解在方法的入參上

@ModelAttribute注解在方法的入參上的例子代码如下:

    /**
     * 此方法可以,在页面中使用${user.name}即可访问
     * */
    @RequestMapping(value = "/testModelAttribute.do",method = RequestMethod.GET)
    public String testModelAttribute(@ModelAttribute("user") User user ){
        user.setName("wojiushimogui");
        return "modelAttribute";

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

modelAttribute.jsp内容如下:

    <html>
    <body>

    <h2>name:${user.name}</h2>

    </body>
    </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

测试结果如下:

当入參是String类型对象时,如下所示:

    /**
     * 此方法不行,在页面中使用${name}不能访问
     * */
    @RequestMapping(value = "/testModelAttribute2.do",method = RequestMethod.GET)
    public String testModelAttribute(@ModelAttribute("name") String name ){
        name="wojiushimogui2";
        return "modelAttribute2";

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

modelAttribute2.jsp内容如下:

    <html>
    <body>

    <h2>name:${name}</h2>
    </body>
    </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当运行时,结果如下:

从结果可以看出,name为空,原因目前不知道是需要显示的将String类型的name保存在模型对象中,还是应为name是字符串的原因所导致.

最后看下如何将接受到的参数写入到视图中

实现代码,使用@ModelAttribute注解如下:

    @ModelAttribute
    public void para(@RequestParam("name") String name,Model model){
        model.addAttribute("name",name);

    }
    @RequestMapping(value = "/testModelAttribute3.do",method = RequestMethod.GET)
    public String testModelAttribute2(){
        return "modelAttribute2";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

相应的jsp文件核心内容为:${name} 
测试结果如下:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值