Spring MVC 中Model, ModelMap, ModelAndView 之間有什么關系和區別?

在 Spring MVC 中,Model, ModelMap, 和 ModelAndView 都是用來在 Controller 和 View 之間傳遞數據的,但它們在使用方式和功能上有所不同。

它們的核心在于:Spring MVC 需要知道兩件事來渲染視圖:① 數據 (Model) ② 視圖名稱 (View Name)

下面我們詳細介紹一下它們的關系和區別:

  1. Model (接口)

    • 是什么Model 是一個接口 (org.springframework.ui.Model)。它主要用于在 Controller 方法中添加需要在 View 中展示的數據。
    • 如何工作:當我們在 Controller 方法的參數中聲明一個 Model 類型的參數時,Spring MVC 會自動創建一個 Model 的實例(通常是 ExtendedModelMap 的實例)并將其傳遞給我們的方法。
    • 主要方法
      • addAttribute(String attributeName, Object attributeValue): 添加單個屬性。
      • addAttribute(Object attributeValue): 添加屬性,名稱由類型推斷。
      • addAllAttributes(Map<String, ?> attributes): 添加一個 Map 中的所有屬性。
      • mergeAttributes(Map<String, ?> attributes): 合并一個 Map 中的屬性,如果鍵已存在則覆蓋。
      • containsAttribute(String attributeName): 檢查是否存在某個屬性。
    • 視圖選擇:當使用 Model 時,Controller 方法通常返回一個 String 類型的值,這個字符串就是邏輯視圖名。Spring MVC 會根據這個視圖名找到對應的視圖進行渲染。
    • 示例
      @Controller
      public class MyController {@GetMapping("/showData")public String showData(Model model) {model.addAttribute("message", "Hello from Model!");User user = new User("John Doe", 30);model.addAttribute("user", user);return "dataView"; // 返回邏輯視圖名}
      }
      
  2. ModelMap (類)

    • 是什么ModelMap 是一個類 (org.springframework.ui.ModelMap),它實現了 Model 接口,并且繼承自 java.util.LinkedHashMap
    • 如何工作:與 Model 類似,我們可以在 Controller 方法參數中聲明它,Spring MVC 會提供相應的實例。因為它是一個 Map,所以我們可以使用所有 Map 的方法(如 put(), get() 等)以及 Model 接口定義的方法。
    • Model 的關系ModelMapModel 接口的一個具體實現。當我們使用 Model 接口時,Spring MVC 內部提供的是 ModelMap(或其子類 ExtendedModelMap)的實例。
    • 視圖選擇:與 Model 相同,Controller 方法通常返回一個 String 類型的邏輯視圖名。
    • 為什么存在
      • 提供了 Map 的便利性,如果已經有了一個 Map 對象,可以直接用 addAllAttributesputAll
      • 歷史原因,在泛型廣泛使用前,ModelMap 提供了類型安全(相對于直接使用 Map<String, Object>)。
    • 示例
      @Controller
      public class MyController {@GetMapping("/showDataWithModelMap")public String showDataWithModelMap(ModelMap modelMap) {modelMap.addAttribute("message", "Hello from ModelMap!");modelMap.put("anotherMessage", "Using put method!"); // Map 的方法User user = new User("Jane Doe", 25);modelMap.addAttribute("user", user);return "dataView"; // 返回邏輯視圖名}
      }
      
  3. ModelAndView (類)

    • 是什么ModelAndView 是一個類 (org.springframework.web.servlet.ModelAndView),它是一個容器,同時持有 模型數據 (Model)視圖信息 (View)
    • 如何工作:與 ModelModelMap 不同,ModelAndView 對象是由我們在 Controller 方法中創建并返回的。我們不需要將其聲明為方法參數(雖然也可以,但不常見)。
    • 主要方法/構造函數
      • ModelAndView(String viewName)
      • ModelAndView(String viewName, Map<String, ?> model)
      • ModelAndView(String viewName, String modelName, Object modelObject)
      • addObject(String attributeName, Object attributeValue): 添加模型數據。
      • setViewName(String viewName): 設置邏輯視圖名。
      • setView(View view): 直接設置一個 View 對象。
      • getModel(): 獲取模型數據 (返回一個 Map)。
      • getModelMap(): 獲取模型數據 (返回一個 ModelMap)。
    • 視圖選擇:視圖信息直接包含在 ModelAndView 對象中。
    • 示例
      @Controller
      public class MyController {@GetMapping("/showDataWithModelAndView")public ModelAndView showDataWithModelAndView() {ModelAndView mav = new ModelAndView();mav.setViewName("dataView"); // 設置邏輯視圖名mav.addObject("message", "Hello from ModelAndView!");User user = new User("Peter Pan", 100);mav.addObject("user", user);return mav; // 返回 ModelAndView 對象}
      }
      

關系總結

  • Model 是一個接口,定義了添加數據到模型的基本操作。
  • ModelMapModel 接口的一個實現,它本身是一個 LinkedHashMap,提供了 Map 的操作便利性。
  • ModelAndView 是一個獨立的類,它封裝了模型數據(內部使用 ModelMap 或類似的 Map 結構來存儲數據)和視圖信息。

區別總結

特性Model (接口)ModelMap (類)ModelAndView (類)
類型接口類 (實現 Model, 繼承 LinkedHashMap)
主要職責僅傳遞數據僅傳遞數據 (以 Map 形式)傳遞數據 指定視圖
如何獲取實例作為 Controller 方法參數 (Spring 注入)作為 Controller 方法參數 (Spring 注入)在 Controller 方法中 new 出來并返回
視圖指定Controller 方法返回 String 視圖名Controller 方法返回 String 視圖名視圖名或 View 對象在 ModelAndView 內部設置
返回值String (邏輯視圖名)String (邏輯視圖名)ModelAndView 對象本身
靈活性專注于數據,視圖名解耦專注于數據,視圖名解耦,有 Map 特性數據和視圖緊密耦合在一個對象中

使用場景?

  • Model (推薦)

    • 這是目前最常用和推薦的方式。
    • 當 Controller 方法的主要職責是準備數據,并且視圖名是固定的或者可以通過簡單的字符串返回時。
    • 代碼更簡潔,職責分離更清晰(方法只關注數據,返回類型指明視圖)。
  • ModelMap

    • 如果需要 Map 的特定方法,或者想強調模型數據是一個 Map 結構時。
    • 實際上,由于 Model 接口已經足夠強大,并且 Spring 內部通常用 ModelMap 的子類 ExtendedModelMap 來實現 Model,所以直接使用 Model 接口通常更好。
  • ModelAndView

    • 當 Controller 方法需要根據邏輯動態決定返回哪個視圖,或者需要返回一個具體的 View 對象時。
    • 在一些較早的 Spring MVC 代碼中比較常見。
    • 當你想將數據和視圖信息明確的捆綁在一起返回時。
    • 如果你需要返回 null 來指示不渲染任何視圖(例如,在某些攔截器或特殊處理中),ModelAndView 也可以做到(返回 nullModelAndView)。

Spring MVC 實踐建議:

優先使用 Model 作為方法參數,并讓 Controller 方法返回 String 類型的邏輯視圖名。這種方式更簡潔,也更符合 Spring MVC 的設計,即 Controller 負責處理請求、準備數據,并將邏輯視圖名交給 ViewResolver 去解析。

只有在確實需要將模型和視圖緊密綁定,或者需要動態決定視圖對象本身時,考慮使用 ModelAndViewModelMap 的使用場景相對較少,通常 Model 接口就能滿足需求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905213.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905213.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905213.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

配置Hadoop集群-免密登錄

在 Hadoop 集群中配置免密登錄是確保各節點間高效通信的關鍵步驟。以下是基于 SSH 密鑰認證的免密登錄配置方案&#xff0c;支持主節點&#xff08;NameNode&#xff09;到所有從節點&#xff08;DataNode&#xff09;的無密碼訪問&#xff1a; 1. 環境準備 集群規劃&#xff…

C++類與對象(二):六個默認構造函數(一)

在學C語言時&#xff0c;實現棧和隊列時容易忘記初始化和銷毀&#xff0c;就會造成內存泄漏。而在C的類中我們忘記寫初始化和銷毀函數時&#xff0c;編譯器會自動生成構造函數和析構函數&#xff0c;對應的初始化和在對象生命周期結束時清理資源。那是什么是默認構造函數呢&…

嵌入式培訓之數據結構學習(一)數據結構的基礎概念、線性表

一、基礎概念 1、數據結構&#xff1a;相互之間存在一種或多種特定關系的數據元素的集合。&#xff08;特定關系有邏輯關系與線性關系&#xff09; &#xff08;1&#xff09;邏輯結構 集合&#xff0c;所有數據在同一個集合中&#xff0c;關系平等&#xff08;數組&#xff…

Android Exoplayer 實現多個音視頻文件混合播放以及音軌切換

在之前的文章ExoPlayer中常見MediaSource子類的區別和使用場景中介紹了Exoplayer中各種子MediaSource的使用場景&#xff0c;這篇我們著重詳細介紹下實現多路流混合播放的用法。常見的使用場景有&#xff1a;視頻文件電影字幕、正片視頻廣告視頻、背景視頻背景音樂等。 初始化…

推特逆向算法,推特爬蟲,數據分析,推特關鍵詞搜索

祝大家五一假期快樂&#xff01; 最近推特加了逆向&#xff0c;頻繁出現404&#xff0c;無法正常抓取數據&#xff0c;這里給出推特逆向的思路及代碼&#xff0c;供大家參考學習&#xff01; 本文將介紹如何使用 Python 模擬請求 Twitter 的 GraphQL 接口&#xff0c;結合 re…

圖形化編程平臺的破局之道:從工具同質化到生態差異化

一、同質化困局的底層邏輯剖析 在全球圖形化編程市場中&#xff0c;工具功能趨同已成為行業共識。據 Statista 2024 年數據顯示&#xff0c;主流平臺的基礎功能重合度高達 78%&#xff0c;核心模塊&#xff08;如條件判斷、循環結構&#xff09;的實現方式高度相似。這種現象的…

【Rust】枚舉和模式匹配

目錄 枚舉和模式匹配枚舉的定義Option 枚舉控制流運算符 match簡潔控制流 if let 枚舉和模式匹配 枚舉的定義 結構體給予你將字段和數據聚合在一起的方法&#xff0c;像 Rectangle 結構體有 width 和 height 兩個字段。而枚舉給予你一個途徑去聲明某個值是一個集合中的一員。…

應急響應靶機——WhereIS?

用戶名及密碼&#xff1a;zgsf/zgsf 下載資源還有個解題.exe: 1、攻擊者的兩個ip地址 2、flag1和flag2 3、后門程序進程名稱 4、攻擊者的提權方式(輸入程序名稱即可) 之前的命令&#xff1a; 1、攻擊者的兩個ip地址 先獲得root權限&#xff0c;查看一下歷史命令記錄&#x…

變量函數實戰:高保真APP原型“發票頁面”動態交互教程

變量函數是高保真交互原型設計中常見的高級交互功能&#xff0c;能夠避免重復復制與手動修改頁面元素和邏輯標注&#xff0c;讓演示更有真實體驗感。本文分享一個高保真APP交互原型頁面的實操案例&#xff0c;結合原型設計工具中的變量函數與邏輯判斷功能&#xff0c;手把手教你…

量子加密通信:守護信息安全的未來之盾

摘要 在數字化時代&#xff0c;信息安全成為全球關注的焦點。傳統加密技術面臨著被量子計算破解的風險&#xff0c;而量子加密通信作為一種基于量子力學原理的新型加密技術&#xff0c;提供了理論上無條件安全的通信保障。本文將詳細介紹量子加密通信的基本原理、技術實現、應用…

《Vue.js》閱讀之響應式數據與副作用函數

Vue.js 《Vue.js設計與實現》&#xff08;霍春陽&#xff09; 適合&#xff1a;從零手寫Vue3響應式系統&#xff0c;大廠面試源碼題直接覆蓋。重點章節&#xff1a;第4章&#xff08;響應式&#xff09;、第5章&#xff08;渲染器&#xff09;、第8章&#xff08;編譯器&…

數據處理專題(十三)

學會基本的圖像處理技術。? OpenCV 基礎 實踐&#xff1a;使用 OpenCV 進行圖像讀取、顯示和基本處理? 03 代碼示例 1. 導入必要的庫 import cv2import numpy as npimport matplotlib.pyplot as plt 2. 圖像讀取 # 讀取圖像image_path path_to_your_image.jpg # 替換…

springboot旅游小程序-計算機畢業設計源碼76696

目 錄 摘要 1 緒論 1.1研究背景與意義 1.2研究現狀 1.3論文結構與章節安排 2 基于微信小程序旅游網站系統分析 2.1 可行性分析 2.1.1 技術可行性分析 2.1.2 經濟可行性分析 2.1.3 法律可行性分析 2.2 系統功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系統…

P1874 快速求和

目錄 題目算法標簽: 動態規劃, 線性 d p dp dp思路代碼 題目 P1874 快速求和 算法標簽: 動態規劃, 線性 d p dp dp 思路 求的是最少組成 n n n的加法次數, 對于當前數字序列可以設計狀態表示 f [ i ] [ j ] f[i][j] f[i][j]表示考慮前 i i i個字符, 并且和是 j j j的所有方…

知名人工智能AI培訓公開課內訓課程培訓師培訓老師專家咨詢顧問唐興通AI在金融零售制造業醫藥服務業創新實踐應用

AI賦能未來工作&#xff1a;引爆效率與價值創造的實戰營 AI驅動的工作革命&#xff1a;從效率提升到價值共創 培訓時長&#xff1a; 本課程不僅是AI工具的操作指南&#xff0c;更是面向未來的工作方式升級羅盤。旨在幫助學員系統掌握AI&#xff08;特別是生成式AI/大語言模型…

Linux 內核參數

文章目錄 什么是內核參數參數種類配置方式1. 編譯內核時配置2. 內核啟動時配置3. 內核運行時配置4. 加載內核模塊時配置總結 什么是內核參數 內核參數是 Linux 系統中用于控制和調整內核行為的可配置選項。這些參數影響系統的性能、安全性和各種功能特性。 參數種類 大部分參…

pythonocc 拉伸特征

micromamba install -c conda-forge pythonocc-core opencascade.js安裝不起來&#xff0c;ai用pythonocc練個手 拉伸線框 線成面 from OCC.Core.gp import gp_Pnt, gp_Dir, gp_Vec from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire f…

Vue.js 頁面切換空白與刷新 404 問題深度解析

在使用 Vue.js 開發單頁應用 (SPA) 的過程中&#xff0c;開發者經常會遇到兩個常見問題&#xff1a;頁面切換時出現短暫的空白屏幕&#xff0c;以及刷新頁面時返回 404 錯誤。這兩個問題不僅影響用戶體驗&#xff0c;還可能阻礙項目的正常上線。本文將深入探討這兩個問題的成因…

Go 語言 slice(切片) 的使用

序言 在許多開發語言中&#xff0c;動態數組是必不可少的一個組成部分。在實際的開發中很少會使用到數組&#xff0c;因為對于數組的大小大多數情況下我們是不能事先就確定好的&#xff0c;所以他不夠靈活。動態數組通過提供自動擴容的機制&#xff0c;極大地提升了開發效率。這…

Qt5.14.2 鏈接 MySQL 8.4 遇到的問題

問題一: "Plugin caching_sha2_password could not be loaded: 找不到指定的模塊。 Library path is caching_sha2_password.dll QMYSQL: Unable to connect" 解決方法: alter user root@localhost identified with mysql_native_password by root;問題二: ERR…