org.springframework.ui.ModelMap 是 Spring MVC 提供的數據傳遞容器,本質上繼承自 LinkedHashMap<String, Object>,保持插入順序。它的核心使命是:將控制器(Controller)處理完的模型數據,透明地傳遞給視圖(View)進行渲染。你可以把它理解為「加強版的 request.setAttribute()」,但更優雅、更安全、更符合 MVC 解耦思想。
@Controller
public class UserController {
@GetMapping("/profile")
public String showProfile(ModelMap modelMap) {
// 單個屬性
modelMap.addAttribute("username", "張三");
modelMap.addAttribute("age", 25);
// 批量放入(鍵值對)
modelMap.addAllAttributes(Map.of(
"email", "zhangsan@example.com",
"roles", List.of("USER", "ADMIN")
));
// 甚至可以直接放入對象,鍵默認為類名首字母小寫
User user = new User("李四", 30);
modelMap.addAttribute(user); // 鍵為 "user"
return "user/profile"; // 視圖名
}
}
視圖技術無關,統一通過 EL 表達式 或模板語法訪問:
${username}、${user.age}、${username}、${user.age}modelMap.addAttribute("a", 1)
.addAttribute("b", 2)
.addAttribute("c", 3);
ModelMap base = new ModelMap("siteName", "MyApp");
ModelMap page = new ModelMap("pageTitle", "首頁");
page.addAllAttributes(base); // 繼承通用數據
若放入 List<User> users,視圖中可直接用 ${users[0].name} 訪問首元素。
| 介面/類 | 適用場景 | 優缺點 |
|---|---|---|
Model (介面) |
最通用,僅需存數據,不關心視圖 | ✅ 解耦最徹底,推薦日常使用 |
ModelMap (類) |
需利用 Map 特性(合併、鏈式、順序) | ✅ 功能豐富,但耦合具體實現類 |
ModelAndView (類) |
需同時控制視圖名與模型數據 | ✅ 一站式返回,但略顯笨重 |
建議:優先使用 Model 介面作為方法參數,僅在需要 Map 特有操作時才注入 ModelMap。返回 String 視圖名最輕量。
addAttribute 會覆蓋,若需保留多值請用 List 或不同鍵名。@SessionAttributes 會將模型屬性存入 Session,若不清理會導致內存洩漏或數據殘留,務必在流程結束調用 SessionStatus.setComplete()。public class ModelMap extends LinkedHashMap<String, Object> {
// 核心邏輯就這樣,簡單優雅
public ModelMap addAttribute(String key, Object value) {
put(key, value);
return this;
}
}
ModelMap 是 Spring MVC 「模型-視圖分離」的關鍵紐帶。掌握其 Map 特性、鏈式 API、與視圖解析器的協作機制,能讓你寫出更乾淨、可維護的控制器代碼。記住:用 Model 接口收參,用 String 返回視圖,才是最標準的 Spring MVC 風格。