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 {