SpringMVC框架做为一个MVC框架,很重要的一项工做是在控制器获取模型数据并返回给客户端,即在JSP页面展现模型数据,使用的技术是经过EL表达式从域对象中取值。html
在Servlet中,咱们能够直接调用web资源给域对象传值,在SpringMVC框架中,如何完成这个操做?今天咱们就来学习SpringMVC框架的模型数据绑定。java
首先来理解这句话,模型数据的绑定,指将模型数据绑定给JSP域对象,回顾一下域对象有哪些?web
JSP四大做用域对应的四个内置对象分别是tomcat
pageContext,request,session,application。session
模型数据的绑定是由ViewResolver来完成的,开发时,咱们先添加模型数据,再交给ViewResolver来绑定。app
因此咱们学习的重点在于如何添加模型数据。框架
SpringMVC提供了如下几种方式添加模型数据:jsp
Map学习
Modelui
ModelAndView
@SessionAttributes
@ModelAttribute
开发中常常用到的域对象是request和session,因此针对这两个域对象进行讲解,pageContext和application能够经过获取原生Servlet资源的方式进行绑定,实际开发中使用很少。
模型数据绑定到request域对象
1.Map
SpringMVC在内部使用Model接口存储模型数据,在调用业务方法前会建立一个隐含对象做为模型数据的存储容器。
设置业务方法的入参为Map类型,SpringMVC会将隐含对象的引用传递给入参。在方法体中,开发者能够经过入参对象访问到模型中的全部数据,也能够向模型中添加新数据。
即只须要在业务方法添加Map类型的入参,方法体中即可经过对入参的操做来完成模型数据的添加。
@RequestMapping("/mapTest") public String mapTest(Map<String,Object> map){ User user = new User(); user.setId(1); user.setName("张三"); map.put("user", user); return "index"; }
业务方法完成,返回模型数据和视图信息给DispatcherServlet,DispatcherServlet经过ViewResolver对视图信息进行解析,逻辑视图映射到物理视图,同时将模型数据绑定到JSP的request域对象中,在JSP页面,可直接经过EL表达式取值。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> ${user.name } </body> </html>
启动tomcat,运行。
2.Model
Model与Map相似,业务方法经过入参来完成模型数据的绑定。
@RequestMapping("/modelTest") public String modelTest(Model model){ User user = new User(); user.setId(1); user.setName("张三"); model.addAttribute("user", user); return "index"; }
3.ModelAndView
与Map或者Model不一样的是,ModelAndView不但包含模型数据,同时也包含了视图信息,因此使用ModelAndView来处理模型数据,业务方法的返回值必须是ModelAndView。
业务方法中对ModelAndView进行两个操做:1.填充模型数据。2.绑定视图信息。
关于ModelAndView的使用有8种方式。
@RequestMapping("/modelAndViewTest1") public ModelAndView modelAndViewTest1(){ ModelAndView modelAndView = new ModelAndView(); User user = new User(); user.setId(1); user.setName("张三"); modelAndView.addObject("user", user); modelAndView.setViewName("index"); return modelAndView; } @RequestMapping("/modelAndViewTest2") public ModelAndView modelAndViewTest2(){ ModelAndView modelAndView = new ModelAndView(); User user = new User(); user.setId(1); user.setName("张三"); modelAndView.addObject("user", user); View view = new InternalResourceView("/index.jsp"); modelAndView.setView(view); return modelAndView; } @RequestMapping("/modelAndViewTest3") public ModelAndView modelAndViewTest3(){ ModelAndView modelAndView = new ModelAndView("index"); User user = new User(); user.setId(1); user.setName("张三"); modelAndView.addObject("user", user); return modelAndView; } @RequestMapping("/modelAndViewTest4") public ModelAndView modelAndViewTest4(){ View view = new InternalResourceView("/index.jsp"); ModelAndView modelAndView = new ModelAndView(view); User user = new User(); user.setId(1); user.setName("张三"); modelAndView.addObject("user", user); return modelAndView; } @RequestMapping("/modelAndViewTest5") public ModelAndView modelAndViewTest5(){ Map<String,Object> map = new HashMap<String,Object>(); User user = new User(); user.setId(1); user.setName("张三"); map.put("user", user); ModelAndView modelAndView = new ModelAndView("index", map); return modelAndView; } @RequestMapping("/modelAndViewTest6") public ModelAndView modelAndViewTest6(){ Map<String,Object> map = new HashMap<String,Object>(); User user = new User(); user.setId(1); user.setName("张三"); map.put("user", user); View view = new InternalResourceView("/index.jsp"); ModelAndView modelAndView = new ModelAndView(view, map); return modelAndView; } @RequestMapping("/modelAndViewTest7") public ModelAndView modelAndViewTest7(){ User user = new User(); user.setId(1); user.setName("张三"); ModelAndView modelAndView = new ModelAndView("index", "user", user); return modelAndView; } @RequestMapping("/modelAndViewTest8") public ModelAndView modelAndViewTest8(){ User user = new User(); user.setId(1); user.setName("张三"); View view = new InternalResourceView("/index.jsp"); ModelAndView modelAndView = new ModelAndView(view, "user", user); return modelAndView; }
4.HttpServletRequest
SpringMVC能够在业务方法直接获取到Servlet原生web资源,只需在方法定义时添加HttpServletRequest入参便可,在方法体中,可直接对request对象进行操做。
@RequestMapping("requestTest") public String requestTest(HttpServletRequest request){ User user = new User(); user.setId(1); user.setName("张三"); request.setAttribute("user", user); return "index"; }
5.@ModelAttribute
SpringMVC还能够经过@ModelAttribute注解的方式添加模型数据,如何使用呢?
1.定义一个方法,该方法用来返回要填充到模型数据中的对象。
2.给该方法添加@ModelAttribute注解。
注意,该方法并非响应请求的业务方法。
@RequestMapping("/modelAttributeTest") public String modelAttributeTest(){ return "index"; } @ModelAttribute public User getUser(){ User user = new User(); user.setId(1); user.setName("张三"); return user; }
添加@ModelAttribute注解的方法,会在SpringMVC在调用任何一个业务方法以前被自动调用。
因此在执行modelAttributeTest业务方法以前,会首先调用getUser方法,获取返回值user对象,SpringMVC框架会自动将该对象填充到模型数据中,进而绑定到域对象中。
咱们知道域对象中的数据都是以键值对(key-value)的形式保存的,那么此时的key是什么呢?默认取模型数据对应类的类名首字母小写,即User类首字母小写"user",因此JSP页面中,能够直接经过"user"取值。
若getUser没有放回值,则必须手动在该方法中填充模型数据,使用Map或者Model。
@ModelAttribute public void getUser2(Map<String,Object> map){ User user = new User(); user.setId(1); user.setName("张三"); map.put("user", user); } @ModelAttribute public void getUser3(Model model){ User user = new User(); user.setId(1); user.setName("张三"); model.addAttribute("user", user); }
模型数据绑定到session域对象
以上的方式所有是将模型数据绑定到request对象中,若是须要将模型数据绑定到session对象中,只须要在类定义处添加@SessionAttributes(value="user")注解便可。
@Controller @SessionAttributes(value="user") public class HelloHandler {
此时,不管经过上述哪一种方式执行业务代码,将模型数据绑定到request对象中的同时,也会将模型数据绑定到session对象中,request和session对象中同时存在模型数据。
@SessionAttributes除了能够经过key值绑定,还能够经过模型数据的数据类型绑定。
@Controller @SessionAttributes(types=User.class) public class HelloHandler {
@SessionAttributes可同时绑定多个模型数据。
@Controller @SessionAttributes(value={"user","address"}) public class HelloHandler {
@Controller @SessionAttributes(types={User.class,Address.class}) public class HelloHandler {