1. 程式人生 > >SpringMVC系列(十三)異常處理

SpringMVC系列(十三)異常處理

supported per ring servlet 標記 ext test 頁面 ansi

一、簡介

? Spring MVC 通過 HandlerExceptionResolver 處理程序的異常,包括 Handler 映射、數據綁定以及目標方法執行時發生的異常。
? SpringMVC 提供的 HandlerExceptionResolver 的實現類

? DispatcherServlet 默認裝配的 HandlerExceptionResolver :
– 沒有使用 <mvc:annotation-driven/> 配置:

技術分享圖片

– 使用了 <mvc:annotation-driven/> 配置:

技術分享圖片

二、ExceptionHandlerExceptionResolver

在 @ExceptionHandler 方法的入參中可以加入 Exception 類型的參數, 該參數即對應發生的異常對象
@ExceptionHandler 方法的入參中不能傳入 Map. 若希望把異常信息傳導頁面上, 需要使用 ModelAndView 作為返回值
@ExceptionHandler 方法標記的異常有優先級的問題.
@ControllerAdvice: 如果在當前 Handler 中找不到 @ExceptionHandler 方法來出來當前方法出現的異常, 則將去 @ControllerAdvice 標記的類中查找@ExceptionHandler 標記的方法來處理異常.

1. 編寫異常handle

 1     @ExceptionHandler({RuntimeException.class})
 2     public ModelAndView handleArithmeticException2(Exception ex){
 3         System.out.println("[出異常了]: " + ex);
 4         ModelAndView mv = new ModelAndView("error");
 5         mv.addObject("exception", ex);
 6         return mv;
 7     }
 8
9 ////優先級高於handleArithmeticException2,如果沒有找到具體的異常就使用handleArithmeticException2 10 @ExceptionHandler({ArithmeticException.class}) 11 public ModelAndView handleArithmeticException(Exception ex){ 12 System.out.println("出異常了: " + ex); 13 ModelAndView mv = new ModelAndView("error"); 14 mv.addObject("exception", ex); 15 return mv; 16 } 17 18 @RequestMapping("/testExceptionHandlerExceptionResolver") 19 public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i){ 20 System.out.println("result: " + (10 / i)); 21 return "success"; 22 }

2.在jsp頁面發送請求

1 <a href="testExceptionHandlerExceptionResolver?i=0">Test ExceptionHandlerExceptionResolver</a>

3. 編寫錯誤回顯的頁面error.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10 
11     <h4>Error Page</h4>
12 
13     ${requestScope.exception }
14 
15 </body>
16 </html>

技術分享圖片

備註:

如果在當前 Handler 中找不到 @ExceptionHandler 方法來出來當前方法出現的異常, 則將去 @ControllerAdvice 標記的類中查找@ExceptionHandler 標記的方法來處理異常.

 1 @ControllerAdvice
 2 public class SpringMVCTestExceptionHandler {
 3 
 4     @ExceptionHandler({ArithmeticException.class})
 5     public ModelAndView handleArithmeticException(Exception ex){
 6         System.out.println("----> 出異常了: " + ex);
 7         ModelAndView mv = new ModelAndView("error");
 8         mv.addObject("exception", ex);
 9         return mv;
10     }
11     
12 }

三、ResponseStatusExceptionResolver

在異常及異常父類中找到 @ResponseStatus 註解,然後使用這個註解的屬性進行處理。

1.定義一個 @ResponseStatus 註解修飾的異常類

 1 @ResponseStatus(value=HttpStatus.FORBIDDEN, reason="用戶名和密碼不匹配!")
 2 public class UserNameNotMatchPasswordException extends RuntimeException{
 3 
 4     /**
 5      * 
 6      */
 7     private static final long serialVersionUID = 1L;
 8 
 9     
10 }

2.編寫handle

使用@ResponseStatus標註的方法即使沒有異常也會報異常

 1 @ResponseStatus(reason="測試",value=HttpStatus.NOT_FOUND)
 2     @RequestMapping("/testResponseStatusExceptionResolver")
 3     public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
 4         if(i == 13){
 5             throw new UserNameNotMatchPasswordException();
 6         }
 7         System.out.println("testResponseStatusExceptionResolver...");
 8         
 9         return "success";
10     }

3.在jsp頁面發送請求

1 <a href="testResponseStatusExceptionResolver?i=13">Test ResponseStatusExceptionResolver</a>

使用@ResponseStatus標註的方法即使沒有異常也會報異常

技術分享圖片

技術分享圖片

四、DefaultHandlerExceptionResolver

對一些特殊的異常進行處理,比如NoSuchRequestHandlingMethodException、HttpRequestMethodNotSupportedException、HttpMediaTypeNotSupportedException、HttpMediaTypeNotAcceptableException等

1.編寫handle

1 @RequestMapping(value="/testDefaultHandlerExceptionResolver",method=RequestMethod.POST)
2     public String testDefaultHandlerExceptionResolver(){
3         System.out.println("testDefaultHandlerExceptionResolver...");
4         return "success";
5     }

2.在jsp頁面發送請求

1 <a href="testDefaultHandlerExceptionResolver">Test DefaultHandlerExceptionResolver</a>

技術分享圖片

五、SimpleMappingExceptionResolver

如果希望對所有異常進行統一處理,可以使用SimpleMappingExceptionResolver,它將異常類名映射為視圖名,即發生異常時使用對應的視圖報告異常

1. 在springmvc.xml配置SimpleMappingExceptionResolver

1 <!-- 配置使用 SimpleMappingExceptionResolver 來映射異常 -->
2     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
3         <property name="exceptionAttribute" value="ex"></property>
4         <property name="exceptionMappings">
5             <props>
6                 <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
7             </props>
8         </property>
9     </bean>    

2. 編寫handle

1 @RequestMapping("/testSimpleMappingExceptionResolver")
2     public String testSimpleMappingExceptionResolver(@RequestParam("i") int i){
3         String [] vals = new String[10];
4         System.out.println(vals[i]);
5         return "success";
6     }

3.在jsp頁面發送請求

1 <a href="testSimpleMappingExceptionResolver?i=12">Test SimpleMappingExceptionResolver</a>

技術分享圖片

SpringMVC系列(十三)異常處理