SpringMVC中@ModelAttribute註解的使用
阿新 • • 發佈:2020-08-28
在SpringMVC的Controller中使用@ModelAttribute
時,其位置包括下面三種:
-
應用在方法上
-
應用在方法的引數上
-
應用在方法上,並且方法也使用了
一、應用在方法上
首先說明一下,被@ModelAttribute
註解的方法會在Controller
每個方法執行之前都執行,因此對於一個Controller
中包含多個URL的時候,要謹慎使用。
1、使用@ModelAttribute
註解無返回值的方法
@Controller @RequestMapping(value = "/modelattribute") public class ModelAttributeController { @ModelAttribute public void myModel(@RequestParam(required = false) String abc, Model model) { model.addAttribute("attributeName", abc); } @RequestMapping(value = "/method") public String method() { return "method"; } }
這個例子,在請求/modelattribute/method?abc=aaa
後,會先執行myModel
方法,然後接著執行method
方法,引數abc
的值被放到Model
中後,接著被帶到method
方法中。
當返回檢視/modelattribute/method
時,Model
會被帶到頁面上,當然你在使用@RequestParam
的時候可以使用required
來指定引數是否是必須的。
如果把myModel
和method
合二為一,程式碼如下,這也是我們最常用的方法:
@RequestMapping(value = "/method") public String method(@RequestParam(required = false) String abc, Model model) { model.addAttribute("attributeName", abc); return "method"; }
2、使用@ModelAttribute
註解帶有返回值的方法
@ModelAttribute public String myModel(@RequestParam(required = false) String abc) { return abc; } @ModelAttribute public Student myModel(@RequestParam(required = false) String abc) { Student student = new Student(abc); return student; } @ModelAttribute public int myModel(@RequestParam(required = false) int number) { return number; }
對於這種情況,返回值物件會被預設放到隱含的Model
中,在Model
中的key
為返回值首字母小寫
,value
為返回的值。
上面3種情況等同於:
model.addAttribute("string", abc); model.addAttribute("int", number); model.addAttribute("student", student);
在jsp頁面使用
${int}
表示式時會報錯:javax.el.ELException: Failed to parse the expression [${int}]
。
解決辦法:
在tomcat的配置檔案conf/catalina.properties
新增配置org.apache.el.parser.SKIP_IDENTIFIER_CHECK=true
如果只能這樣,未免太侷限了,我們很難接受key
為string
、int
、float
等等這樣的。
想自定義其實很簡單,只需要給@ModelAttribute
新增value
屬性即可,如下:
@ModelAttribute(value = "num") public int myModel(@RequestParam(required = false) int number) { return number; }
這樣就相當於model.addAttribute("num", number);
。
二、使用@ModelAttribute註解的引數
@Controller @RequestMapping(value = "/modelattribute") public class ModelAttributeParamController { @ModelAttribute(value = "attributeName") public String myModel(@RequestParam(required = false) String abc) { return abc; } @ModelAttribute public void myModel3(Model model) { model.addAttribute("name", "zong"); model.addAttribute("age", 20); } @RequestMapping(value = "/param") public String param(@ModelAttribute("attributeName") String str, @ModelAttribute("name") String str2, @ModelAttribute("age") int str3) { return "param"; } }
從程式碼中可以看出,使用@ModelAttribute
註解的引數,意思是從前面的Model
中提取對應名稱的屬性。
這裡提及一下@SessionAttributes
的使用:
- 如果在類上面使用了
@SessionAttributes("attributeName")
註解,而本類中恰巧存在attributeName
,則會將attributeName
放入到session
作用域。- 如果在類上面使用了
@SessionAttributes("attributeName")
註解,SpringMVC會在執行方法之前,自動從session
中讀取key
為attributeName
的值,並注入到Model
中。所以我們在方法的引數中使用ModelAttribute("attributeName")
就會正常的從Model
讀取這個值,也就相當於獲取了session
中的值。- 使用了
@SessionAttributes
之後,Spring無法知道什麼時候要清掉@SessionAttributes
存進去的資料,如果要明確告知,也就是在方法中傳入SessionStatus
物件引數,並呼叫status.setComplete
就可以了。
三、應用在方法上,並且方法上也使用了@RequestMapping
@Controller @RequestMapping(value = "/modelattribute") public class ModelAttributeController { @RequestMapping(value = "/test") @ModelAttribute("name") public String test(@RequestParam(required = false) String name) { return name; } }
這種情況下,返回值String(或者其他物件)就不再是檢視了,而是放入到
Model
中的值,此時對應的頁面就是@RequestMapping
的值test
。如果類上有
@RequestMapping
,則檢視路徑還要加上類的@RequestMapping
的值,本例中檢視路徑為modelattribute/test.jsp
。
作者:Java_Explorer
連結:https://www.jianshu.com/p/0ec4e7afb7ed
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。