Spring MVC @ModelAttribute 詳解
[email protected]註釋void返回值的方法
@Controller public class HelloModelController { @ModelAttribute public void populateModel(@RequestParam String abc, Model model) { model.addAttribute("attributeName", abc); } @RequestMapping(value = "/helloWorld") public String helloWorld() { return "helloWorld.jsp"; } }
在這個程式碼中,訪問控制器方法helloWorld時,會首先呼叫populateModel方法,將頁面引數abc(/helloWorld.ht?abc=text)放到model的attributeName屬性中,在檢視中可以直接訪問。
jsp頁面頁面如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> </head> <body> <c:out value="${attributeName}"></c:out> </body> </html>
[email protected]ttribute註釋返回具體類的方法
@Controller public class Hello2ModelController { @ModelAttribute public User populateModel() { User user=new User(); user.setAccount("ray"); return user; } @RequestMapping(value = "/helloWorld2") public String helloWorld() { return "helloWorld.jsp"; } }
當用戶請求 http://localhost:8080/test/helloWorld2.html時,首先訪問populateModel方法,返回User物件,model屬性的名稱沒有指定,它由返回型別隱含表示,如這個方法返回User型別,那麼這個model屬性的名稱是user。
這個例子中model屬性名稱有返回物件型別隱含表示,model屬性物件就是方法的返回值。它無須要特定的引數。
jsp 中如下訪問:
<c:out value="${user.account}"></c:out>
也可以指定屬性名稱
@Controller
public class Hello2ModelController {
@ModelAttribute(value="myUser")
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld(Model map) {
return "helloWorld.jsp";
}
}
jsp中如下訪問:
<c:out value="${myUser.account}"></c:out>
物件合併:
@Controller
public class Hello2ModelController {
@ModelAttribute
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld(User user) {
user.setName("老王");
return "helloWorld.jsp";
}
}
物件合併指定物件名稱:
@Controller
public class Hello2ModelController {
@ModelAttribute("myUser")
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld(@ModelAttribute("myUser") User user) {
user.setName("老王");
return "helloWorld.jsp";
}
}
這樣在jsp中可以使用如下方式訪問
<c:out value="${myUser.name}"></c:out>
<c:out value="${myUser.account}"></c:out>
3.通過此特性控制權限.
我們可以在基類方法中控制寫此註解,需要控制權限的控制器,繼承控制器就可以了。
public class BaseController {
@ModelAttribute
public void populateModel() throws Exception {
SysUser user=ContextUtil.getCurrentUser();
if(user.getAccount().equals("admin")){
throw new Exception("沒有許可權");
}
}
}
需要控制權限的類繼承BaseController
@Controller
public class Hello2ModelController extends BaseController {
@RequestMapping(value = "/helloWorld2")
public String helloWorld(@ModelAttribute("myUser") User user) {
user.setName("老王");
return "helloWorld.jsp";
}
}
這樣就可以控制權限了,當然控制權限的方法有很多,比如通過過濾器等。這裡只是提供一種思路。
總結:
@ModelAttribute具有如下三個作用:
①繫結請求引數到命令物件:放在功能處理方法的入參上時,用於將多個請求引數繫結到一個命令物件,從而簡化繫結流程,而且自動暴露為模型資料用於檢視頁面展示時使用。其實@ModelAttribute此處對於供檢視頁面展示來說與model.addAttribute("attributeName", abc);功能類似。
public String test(@ModelAttribute("user") UserModel user)
此處多了一個註解@ModelAttribute("user"),它的作用是將該繫結的命令物件以“user”為名稱新增到模型物件中供檢視頁面展示使用。我們此時可以在檢視頁面使用${user.username}來獲取繫結的命令物件的屬性。
②暴露@RequestMapping 方法返回值為模型資料:放在功能處理方法的返回值上時,是暴露功能處理方法的返回值為模型資料,用於檢視頁面展示時使用。
public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user)
大家可以看到返回值型別是命令物件型別,而且通過@ModelAttribute("user2")註解,此時會暴露返回值到模型資料( 名字為user2 ) 中供檢視展示使用
@ModelAttribute 註解的返回值會覆蓋@RequestMapping 註解方法中的@ModelAttribute 註解的同名命令物件
③暴露表單引用物件為模型資料:放在處理器的一般方法(非功能處理方法)上時,是為表單準備要展示的表單引用物件,如註冊時需要選擇的所在城市等,而且在執行功能處理方法(@RequestMapping 註解的方法)之前,自動新增到模型物件中,用於檢視頁面展示時使用;