1.@SessionAttributes(String[] value,Class[] types)的使用(一種向session域中添加屬性的方式)
加在handler類上。
>當響應的目標方法中有向request域中添加屬性的操作時,若該屬性名與value值中的一個相同,就將它也添加到session中;
或者該屬性類型與types中的一個相同,就將它也添加到session中。
2.ModelAttribute
MyHandler.java
package handler; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.servlet.ModelAndView; import model.User; @SessionAttributes(value = { "username", }, types = { String.class }) @Controller public class Handler { public static final String SUCCESS = "success"; /** * 任何通過這個Handler的請求在執行目標方法之前都要執行@ModelAttribute修飾的getModel方法 * 形參中的user只有表單上提交的屬性值 * 從數據庫中取出對應的屬性放到request中 * */ @ModelAttribute public void getModel(User user, Model map) { System.out.println("一"+user); if (user.getId() != null) { map.addAttribute("abc", new User(1, "Ji", "123")); } } /**(三個標*重點) * 模擬edit的一個場景。使表單上提交的項被賦到從數據庫中得到的對象,而不是新的空對象。這樣不能修改的項就不會為null * 表面的運行流程: * 1.執行@ModelAttribute注釋的方法,從數據庫中獲取對應的對象並放入到request域中 * 2.springMVC會將request域中以User(形參類型名)首字母小寫為屬性名的對象取出,將表單上的值賦給其對應的屬性 * 3.目標方法的形參就接受到了覆蓋后的對象 * 注意:若@ModelAttribute("abc")注釋了形參,那么第二步中的user就會變成abc * * 源碼是怎么實現第二步的:(就算沒有寫 @ModelAttribute 注釋的方法也會這么走) * 1.實際上把@ModelAttribute修飾的方法中的Map中的數據放到了implicitModel中 * 2.解析目標方法的參數(就是@ModelAttribute("abc")User user),實際上它來自於WebDataBinder對象的target屬性 * 01.創建WebDataBinder對象 * 001.*確定objectName屬性:若傳入的attrName屬性為""(即沒有用@ModelAttribute("abc")注釋), * 則objectName為參數類型名首字母小寫; * 若有用@ModelAttribute("abc")注釋,attrName為abc,objectName為attrName * 002.確定target屬性: * >首先在implicitModel中查找objectName對應的屬性值若存在就賦給target * >*若不存在:看Handler是否使用了@SessionAttributes(value = { "username", }),再在Session中查找,若 * value中包含objectName,但session中又確實沒有對應的屬性值,那么拋出異常 * >以上若都沒有得到target,那么就通過反射創建一個空的user對象 * 02.springMVC把表單中的請求參數賦給WebDataBinder對象的target屬性,實現覆蓋。 * 03*.springMVC把WebDataBinder的objectName和target給到implicitModel(相當於覆蓋后又放到request域中了) * 04.把WebDataBinder的target傳給形參user。 * */ @RequestMapping("/testModelAttribute") public ModelAndView testModelAttribute(@ModelAttribute("abc")User user) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName(SUCCESS); System.out.println(user); return modelAndView; } @RequestMapping("/testSessionAttributes") public String testSessionAttributes(Model model, HttpSession session) { model.addAttribute("username", "Ji"); model.addAttribute("username2", "Yun"); session.setAttribute("username3", "Fei"); return SUCCESS; } @RequestMapping("/testSpringMVC") public String testSpringMVC() { System.out.println("testSpringMVC"); return SUCCESS; } }