SpringMVC確定目標方法POJO類型的入參過程
1、確認一個key:
(1)、若目標方法的POJO類型的參數沒有使用@ModelAttribute作為修飾,則key為POJO類名第一個字母的小寫
(2)、若使用@ModelAttribute來修飾,則key為@ModelAttibute注解的value屬性值。
1 @RequestMapping("/updateUser") 2 public String update(User user){
這里沒有使用@ModelAttribute修飾,所有對應的key為POJO類名首字母小寫,即為:user
1 public String update(@ModelAttribute("abc") User user)
這里使用了@ModelAttribute來修飾POJO,那么對應的可以為@ModelAttribute的value而值,即為:abc
2、在implicitModel中查找key對應的對象。若存在,則作為參數傳入
(1)、若在@ModelAttibute標記的方法中在Map中保存過POJO,且key和1中確認的key一致,則會獲取。例如:
1 package com.proc; 2 3 import java.util.Map; 4 5 import org.springframework.stereotype.Controller; 6 import org.springframework.web.bind.annotation.ModelAttribute; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestParam; 9 10 @Controller 11 public class UserController { 12 13 14 @ModelAttribute 15 public void getUser(@RequestParam(required=false) Integer id,Map map){ 16 if(id!=null){ 17 User user=new User(); 18 user.setId(1); 19 user.setUsername("caoyc"); 20 user.setAge(18); 21 user.setPassword("123456"); 22 map.put("user", user); 23 } 24 } 25 26 @RequestMapping("/updateUser") 27 public String update(@ModelAttribute("abc") User user){ 28 System.out.println("更新User對象為:"+user); 29 return "success"; 30 } 31 }
JSP頁面
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 7 </head> 8 9 <body> 10 <form action="updateUser" method="post"> 11 <input type="hidden" name="id" value="1"> 12 <table> 13 <tr> 14 <td>用戶名:</td><td><input type="text" name="username" value="caoyc"/></td> 15 </tr> 16 <tr> 17 <td>年齡:</td><td><input type="text" name="age" value="12"/></td> 18 </tr> 19 <tr> 20 <td></td><td><input type="submit" value="提交"></td> 21 </tr> 22 </table> 23 </form> 24 </body> 25 </html>
結果在控制台中輸出:User [id=1, username=caoyc, password=123456, age=12]
其中原因是:在方法/updateUser時對應的方法update( User user)時,先要執行@ModelAttribute標記的方法,而在@ModelAttribute中向implicitModel中保存了一個key為user的POJO對象。而此時update對象中參數的key為POJO類名首字母小寫,也是user,也就是在implicitModel中存在該key和對應的POJO對象。那么就會以該對象作為原始值。而JSP頁面中傳入過來的POJO對象屬性不為空且有變化的屬性來修改原始值。
原始對象:User [id=1, username=caoyc, password=123456, age=18]
JSP中 :User[id=1, username=caoyc, password=null, age=12]
這里需要修改的屬性為age。在原始值得基礎上修改了將age修改為12
所以最總在implicitModel中key值為user的POJO對象為:User [id=1, username=caoyc, password=123456, age=12]
3、座implicitModel中不存在key對應的對象,則檢查當前的Handler是否使用了@SessionAttributes注解修飾,若使用了該注解,且@SessionAttribute注解的value屬性值中包含了key,則會從HttpSession中獲取key所對應的value值,若存在則直接傳入到目標方法的入參中,若不存在則將拋出異常。
Java代碼
1 @SessionAttributes(value={"user"}) 2 @Controller 3 public class UserController { 4 5 @RequestMapping("/updateUser") 6 public String update(User user){ 7 //System.out.println("更新User對象為:"+user); 8 return "success"; 9 } 10 }
此時,如果session中沒有key為user的值,那么只需/updateUser時會拋出異常。因為在只需目標方法時,發現類有@SessionAttributes注解,且目標方法需要一個key為user的POJO對象,該key還存在@SessionAttributes注解的value中,所以會拋出異常。如果此時session中存在key為user的值,則將該值傳入目標方法參數。
怎么解決異常?
方法一:添加一個使用@ModelAttribute的注解的方法,該方法向implicitModel保存一個為key為user的POJO
方法二:去掉@SessionAttributes注解
方法三:修改目標參數的key值。例如 @ModelAttribute(value="user2") User user
4、若Handler沒有標識@SessionAttributes注解或@SessionAttributes注解的value值中不包含key,則會通過反射來創建POJO類型的參數,並作為參數傳入到目標方法
5、SpringMVC會把key和POJO類型的對象保存到imlicitModel中,進而會保存到request中。