SpringMVC:模型數據解析

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 {
相關文章
相關標籤/搜索