springmvc的ModelAttribute註解
阿新 • • 發佈:2019-01-25
參考資料:spring-framework-reference的Using @ModelAttribute on a method和Using @ModelAttribute on a method argument
執行此方法時會將key為"user"(注意:這裡即使引數名稱是user1,key一樣還是"user"),value為user的物件加入到model.在jsp頁面可以通過${user.id}和${user.name}得到值的,即上面方法和下面方法是相當的.
1.在方法上使用@ModelAttribute
使用了@ModelAttribute可修改這個key,不一定是"user",此情況下,用與不用@ModelAttribute沒有區別.
3.再來看看在方法和方法引數上結合使用@ModelAttribute,即上面兩步的兩個方法都新增UserController,如下:
再來個小小假設,將上面@ModelAttribute("user1")的user1改為user,其它不變.雖然執行了addUser方法,那麼執行到save方法內,user物件的欄位值還是來源於請求,最後返回到jsp頁面,model裡也只有一個User型別物件.
4.另類:
先看一個沒有使用@ModelAttribute的Controller方法.
@RequestMapping("/save")
public String save(User user) {
user.setUsername("U love me");
userService.save(user);
return "result";
}
其中User包含id和username兩個私有屬性,含有公共setter和getter方法.執行此方法時會將key為"user"(注意:這裡即使引數名稱是user1,key一樣還是"user"),value為user的物件加入到model.在jsp頁面可以通過${user.id}和${user.name}得到值的,即上面方法和下面方法是相當的.
一.下面再來看看@ModelAttribute的基本用法.@RequestMapping("/save") public String save(Model model,int id,String username) { User user=new User(); //這裡是通過反射從request裡面拿值再set到user user.setId(id); user.setUsername(username); model.addAttribute("user",user); user.setUsername("U love me"); userService.save(user); return "result"; }
1.在方法上使用@ModelAttribute
@ModelAttribute("user1")
public User addUser(User user) {
return new User(520,"I love U");
}
假設此方法是寫在UserController內,那麼執行UserController內帶有@RequestMapping的方法之前,都會先執行此addUser方法.並且執行addUser過程中會新增兩個物件到model,先將key為"user"的物件(由addUser方法的User user引起的),再新增key為"user1"的物件(由註解@ModelAttribute("user1")引起的).2.在方法引數上使用@ModelAttribute.
@RequestMapping("/save")
public String save(@ModelAttribute User user) {
user.setUsername("U love me");
userService.save(user);
return "result";
}
此方法會先從model去獲取key為"user"的物件,如果獲取不到會通過反射例項化一個User物件,再從request裡面拿值set到這個物件,然後把這個User物件新增到model(其中key為"user").使用了@ModelAttribute可修改這個key,不一定是"user",此情況下,用與不用@ModelAttribute沒有區別.
3.再來看看在方法和方法引數上結合使用@ModelAttribute,即上面兩步的兩個方法都新增UserController,如下:
假設要執行儲存使用者操作,根據一分析可知,先執行完會產生兩個User型別的物件(一個key是"user",另一個key是"user1")新增到model,再執行save方法,此時會先從model去找key為"user"的物件,能找到再從request取值set到這個User物件.最後返回到jsp頁面,model裡也只有兩個User型別物件.@ModelAttribute("user1") public User addUser(User user) { return new User(520,"I love U"); } @RequestMapping("/save") public String save(@ModelAttribute User user) { user.setUsername("U love me"); userService.save(user); return "result"; }
再來個小小假設,將上面@ModelAttribute("user1")的user1改為user,其它不變.雖然執行了addUser方法,那麼執行到save方法內,user物件的欄位值還是來源於請求,最後返回到jsp頁面,model裡也只有一個User型別物件.
4.另類:
@ModelAttribute
@RequestMapping("/save")
public String save(@ModelAttribute User user) {
user.setUsername("U love me");
userService.save(user);
return "result";
}
此種情況,會新增一個key為"user"的User物件到model,還會新增一個key為"string",value為"result"的物件到model,而檢視名稱則變為了"save"而不是"result".相信一般開發者都不會這樣用.
二.下面再看看結合@SessionAttributes的用法.
1.先看看這段程式碼
@Controller
@RequestMapping("user")
@SessionAttributes("test")
public class UserController {
@RequestMapping(value = "test1")
public String test1(Map<String, Object> model, SessionStatus sessionStatus) {
model.put("test","something");
//sessionStatus.setComplete();
return "user/list";
}
@RequestMapping(value = "test2")
public String test2(Map<String,?> model) {
Object test = model.get("test");
System.out.println(test);
return "user/list";
}
}
在類級別上使用@SessionAttributes("test"),它的作用是在controller共享 model 屬性,直到呼叫org.springframework.web.bind.support.SessionStatus#setComplete會清除此session值.否則長期保留(session過期,這個值也不再保留).因此先呼叫/user/test1,再呼叫/user/test2.在test2方法能得到test1方法put進去的值.當移除上面的註解,因為屬性為test的session也被清除了,所以test2方法會得到是null.
2.再看結合@ModelAttribute的用法.
@Controller
@RequestMapping("user")
@SessionAttributes("test")
public class UserController {
@RequestMapping(value = "test1")
public String test1(HttpServletRequest request) {
User user = new User("xiejx618");
request.getSession().setAttribute("test",user);
return "user/list";
}
@RequestMapping(value = "test2")
public String test2(@ModelAttribute("test") User user,SessionStatus sessionStatus) {
System.out.println(user.getUsername());
sessionStatus.setComplete();
return "user/list";
}
}
一樣先呼叫/user/test1,再呼叫/user/test2.在test2方法能得到test1方法set進去的值.使用了@SessionAttributes,如果在controller的方法引數上有@ModelAttribute,那麼此方法會確保屬性test的session會存在,否則會拋org.springframework.web.HttpSessionRequiredException異常,即上面程式碼先不調/user/test1,直接調/user/test2就會拋此異常
我個人很少這樣用,用原始的寫法就清晰很多了,但要看明白別人寫的程式碼。