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

来源:互联网 发布:妮维雅怎么样知乎 编辑:程序博客网 时间:2024/05/22 12:03

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;        }    }

该处理方法返回的是一个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>

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

注意:
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";    }

上面代码所对应的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";        }    }

sessionAttribute.jsp的内容如下:

    <html>    <body>    <h2>method:${requestScope.name}</h2>    ${requestScope.time}<br>    ${requestScope.get("time")}<br>    ${time} <br>    sessionScope.time:${sessionScope.time}    </body>    </html>

这样,在浏览器中输入: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";    }

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

modelAttributeInRVMethod.jsp的内容如下:

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

测试结果如下:

还有一点需要说明的是:返回User对象,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称是user,因此,在如上的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;    }

相应的jsp文件内容如下:

    <html>    <body>    <h2>name:${myUser.name}</h2>    <h2>name:${myUser.age}</h2>    </body>    </html>

测试结果如下:

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";    }

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";        }    }

运行结果为:

猜想可不可能与两个使用了@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";    }

测试结果如下:

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

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";    }

modelAttribute.jsp内容如下:

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

测试结果如下:

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

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

modelAttribute2.jsp内容如下:

    <html>    <body>    <h2>name:${name}</h2>    </body>    </html>

当运行时,结果如下:

从结果可以看出,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";    }

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

小结

以上就是关于集中Spring mvc中传递模型数据到视图中的几种方法介绍。 完整的工程代码可以在这里获取:https://github.com/wojiushimogui/springmvcmodel

参考资料

1、http://blog.csdn.net/u010785025/article/details/52770509

2、http://www.cnblogs.com/MrSaver/p/6395684.html

3、http://blog.csdn.net/hejingyuan6/article/details/49995987

5、https://my.oschina.net/u/2321816/blog/546964

0 0
原创粉丝点击