InvocationTargetException異常的深入研究-servlet的setAttribute與getAttribute


在某項目中,前端jsp傳入的用戶id數據通過session域傳入后台servlet進行處理的過程中,無意間出現了InvocationTargetException異常 

前端部分代碼如下:測試代碼,非原項目代碼

 1 // 登錄處理源碼
 2 if ("student".equals(role)) {  3     // 學生登錄  4     // 創建學生服務對象
 5     StudentService ss = new StudentServiceImpl();  6     // 調用服務中的登錄進程
 7     Student student = ss.login(uid, upwd);  8     // 判斷此學生是否存在
 9     if(student != null) { 10         // 如果存在,則登錄成功, 存儲學生信息
11         /* javax.servlet.http.HttpSession源碼 12  * public void setAttribute(String name, Object value); 13         */
14         // 第一種設置域屬性方式:sid 在實體類中定義的是int類型,setAttribute中傳入值則自動裝箱成Integer 15         // req.getSession().setAttribute("uid", student.getSid()); 16         // 第二種設置屬性方式:為了驗證,此處給指定字符串數據
17         req.getSession().setAttribute("uid", "1"); 18         req.getSession().setAttribute("uname", student.getSname()); 19         // 頁面跳轉
20         resp.sendRedirect(req.getContextPath() + "/index.jsp"); 21         return; 22     } else { 23         // 失敗信息
24         req.setAttribute("error", "用戶名或密碼錯誤,請重新登錄!"); 25         // 請求轉發
26         req.getRequestDispatcher("login.jsp").forward(req, resp); 27         return; 28  } 29 }

 

1 <-- 登錄成功后的跳轉鏈接 -->
2 <div>
3     <a href="student.action?operation=queryInfo&uid=${uid }" class="left-font03">查看個人信息</a>
4 </div>

 

 

 1 // 獲取詳細信息的servlet代碼
 2 public void queryInfo(HttpServletRequest req, HttpServletResponse resp){  3     StudentService ss = new StudentServiceImpl();  4     // 直接從url中的參數中獲取uid,為String類型數據  5     //String uid = req.getParameter("uid");  6 
 7     // 第一種獲取uid方式:從登錄時保存在session中屬性獲取,此屬性為int類型,通過setAttribute方法自動裝箱成Integer類型屬性傳遞  8     // int sid = (Integer) req.getSession().getAttribute("uid");  9 
10     // 第二種獲取uid方式:從登錄時保存在session中屬性獲取,此屬性為String類型
11     String uid = req.getSession().getAttribute("uid"); 12 
13     // 出現InvocationTargetException異常的源頭就在此,由於使用getAttribute方法獲取保存在對應域內的屬性值默認屬性為Object, 14     // 此時強轉類型需要使用與原類型匹配的類型,否則在下面語句轉換數據為int類型時會出錯
15     int sid = Integer.parseInt(uid); 16     Student student = ss.queryById(sid); 17     if(cs.queryById(sid) != null ){ 18         req.setAttribute("student", student); 19         try { 20 
21 // 請求轉發 req.getRequestDispatcher("student/information.jsp").forward(req, resp);
22             return; 23         } catch (ServletException e) { 24  e.printStackTrace(); 25         } catch (IOException e) { 26  e.printStackTrace(); 27  } 28  } 29 } 30 
31 // 重寫service方法,通過反射提取方法
32 @Override 33 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 34     // 獲取當前對象所屬類的Class對象
35     Class<?> c = this.getClass(); 36     // 接收想要被調用的方法的名字
37     String name = req.getParameter("operation"); 38     try { 39         // 通過class對象獲取要調用的方法 40         // 如果被調用方法出錯,此處就會抓取異常信息,也就是InvocationTargetException異常的來源
41         Method method = c.getMethod(name, HttpServletRequest.class, HttpServletResponse.class); 42         // 通過反射調用該方法
43         method.invoke(this, req, resp); 44     } catch (Exception e) { 45  e.printStackTrace(); 46  } 47 }

 

下面這段代碼需要特別注意:

  如果在保存屬性時,屬性內容,setAttribute中傳遞的是數字,非字符串,則在接收屬性時,不再需要使用 Integer.parseInt(uid) 對其進行轉換,直接使用 (Integer) req.getSession().getAttribute("uid");進行強轉即可得到對應的數字。此時如果使用String類型變量來接收該屬性,則會存在數據類型不匹配的隱患,然后再使用Integer.parseInt(uid)進行強制類型轉換,就會出現異常,從而導致通過反射調用該方法是出現 InvocationTargetException 異常。

  如果在保存屬性時,屬性內容,setAttribute中傳遞的是由數字用雙引號轉化的字符串,則需要用一個String類型的變量接收獲取的屬性,String uid = req.getSession().getAttribute("uid");然后再使用Integer.parseInt(uid)對其進行強轉后才能向實體對象中保存或做其他用途。

1 // 第一種獲取uid方式:從登錄時保存在session中屬性獲取,此屬性為int類型,通過setAttribute方法自動裝箱成Integer類型屬性傳遞 2 // int sid = (Integer) req.getSession().getAttribute("uid"); 3 // 第二種獲取uid方式:從登錄時保存在session中屬性獲取,此屬性為String類型
4 String uid = req.getSession().getAttribute("uid"); 5 // 出現InvocationTargetException異常的源頭就在此,由於使用getAttribute方法獲取保存在對應域內的屬性值默認屬性為Object, 6 // 此時強轉類型需要使用與原類型匹配的類型,否則在下面語句轉換數據為int類型時會出錯

 



個人總結分享,共同學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM