1. 程式人生 > >Spring MVC @ModelAttribute 詳解

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 註解的方法)之前,自動新增到模型物件中,用於檢視頁面展示時使用;