一.概念
- Spring MVC 通過 HandlerExceptionResolver 處理程序的異常,包括Handler 映射、數(shù)據(jù)綁定以及目標(biāo)方法執(zhí)行時(shí)發(fā)生的異常.
-
SpringMVC 提供的 HandlerExceptionResolver 的實(shí)現(xiàn)類
Paste_Image.png

Paste_Image.png
二.舉例
- SpringMVCTestNew.java 控制器
/**
* 1. 在 @ExceptionHandler 方法的入?yún)⒅锌梢约尤?Exception 類型的參數(shù), 該參數(shù)即對應(yīng)發(fā)生的異常對象
* 2. @ExceptionHandler 方法的入?yún)⒅胁荒軅魅?Map. 若希望把異常信息傳導(dǎo)頁面上, 需要使用 ModelAndView 作為返回值
* 3. @ExceptionHandler 方法標(biāo)記的異常有優(yōu)先級的問題. (優(yōu)先會找與出現(xiàn)異常最接近的異常來處理)
* 4. @ControllerAdvice: 如果在當(dāng)前 Handler 中找不到 @ExceptionHandler 方法來出來當(dāng)前方法出現(xiàn)的異常,
* 則將去 @ControllerAdvice 標(biāo)記的類中查找 @ExceptionHandler 標(biāo)記的方法來處理異常.
*/
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handlerArithmeticException(Exception ex)
{
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
System.out.println("[出現(xiàn)了算數(shù)異常] : " + ex);
return mv;
}
/**
* 測試springMVC對于異常的處理
*/
@RequestMapping("/testExceptionHandlerReslover")
public String testExceptionHandlerReslover(@RequestParam(value="i") Integer i)
{
System.out.println("param i value = " + (10/i));
return "success";
}
- 新建
error.jsp
<h4>Error Page</h4>
<p>exception = ${requestScope.exception}</p>
- 訪問: http://localhost:8081/spring-mvc-2/testExceptionHandlerReslover?i=0
因?yàn)槟繕?biāo)方法被除數(shù)為0,出現(xiàn)算數(shù)異常,所以在java控制臺輸出:
[出現(xiàn)了算數(shù)異常] : java.lang.ArithmeticException: / by zero
前臺頁面輸出:
Error Page
exception = java.lang.ArithmeticException: / by zero
- 此時(shí)如果想讓所有控制器handler都需要處理異常,則需要自己定義類實(shí)現(xiàn), 以下是自己定義的
HandlerException, (注意: 如果在Handler控制器中能找到@ExceptionHandler注釋的方法,則優(yōu)先執(zhí)行該方法)
package com.atguigu.springmvc.tests;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* @ControllerAdvice: 如果在當(dāng)前 Handler 中找不到 @ExceptionHandler 方法來出來當(dāng)前方法出現(xiàn)的異常,
* 則將去 @ControllerAdvice 標(biāo)記的類中查找 @ExceptionHandler 標(biāo)記的方法來處理異常.
* 如果在Handler控制器中能找到@ExceptionHandler注釋的方法,則優(yōu)先執(zhí)行該方法
* @author lxf
*/
@ControllerAdvice
public class HandlerException {
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handlerArithmeticException(Exception ex)
{
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
System.out.println("--->[出現(xiàn)了算數(shù)異常] : " + ex);
return mv;
}
}
使用@ResponseStatus 注解
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver是HandlerExceptionResolver接口的實(shí)現(xiàn)類, 負(fù)責(zé)使用@ResponseStatus注解將HTTP狀態(tài)碼返回.
@ResponseStatus注解可以作用在類和方法上
- 作用在類上, 新建異常類
UserNameNotMatchPasswordException
package com.atguigu.springmvc.tests;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* 自定義異常類
* @author lxf
*
*/
@ResponseStatus(value=HttpStatus.FORBIDDEN, reason=";用戶名和密碼不匹配")
public class UserNameNotMatchPasswordException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
- 在
SpringMVCTestNew控制器中寫方法
/**
* 測試 @ResponseStatus 注解, 將http狀態(tài)碼返回客戶端
* @param i
* @return
*/
@RequestMapping("/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i)
{
if(i == 13)
{
throw new UserNameNotMatchPasswordException();
}else
{
System.out.println("testResponseStatusExceptionResolver...");
}
return "success";
}
測試訪問 : http://localhost:8081/spring-mvc-2/testResponseStatusExceptionResolver?i=13
-
異常輸出:
Paste_Image.png 將注解作用在方法上, 修改控制器中的目標(biāo)方法,新增
@ResponseStatus注解
/**
* 測試 @ResponseStatus 注解, 將http狀態(tài)碼返回客戶端
* @param i
* @return
*/
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="您訪問的頁面不存在!")
@RequestMapping("/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i)
{
if(i == 13)
{
throw new UserNameNotMatchPasswordException();
}else
{
System.out.println("testResponseStatusExceptionResolver...");
}
return "success";
}
-
訪問測試:
Paste_Image.png
DefaultHandlerExceptionResolver 處理springMVC指定的異常返回對應(yīng)Http狀態(tài)
- 在
springMVCTestNew控制器中新增測試目標(biāo)方法
/**
* 測試異常處理DefaultHandlerExceptionResolver處理springMVC指定的異常返回對應(yīng)Http狀態(tài)
* 該處理器必須是post方式請求,如果請求方式為get那么會通過DefaultHandlerExceptionResolver處理
* @return
*/
@RequestMapping(value="/testDefaultHandlerExceptionResolver", method=RequestMethod.POST)
public String testDefaultHandlerExceptionResolver()
{
System.out.println("testDefaultHandlerExceptionResolver");
return "success";
}
-
如果在瀏覽器中請求以上方法,則會拋出異常
Paste_Image.png
SimpleMappingExceptionResolver
對所有異常進(jìn)行統(tǒng)一處理, 可以使用
SimpleMappingExceptionResolver,它將異常類名映射為視圖名,即發(fā)生異常時(shí)使用對應(yīng)的視圖報(bào)告異常
- 配置
springmvc.xml
<!-- 配置SimpleMappingExceptionResolver類映射異常 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 可以在對應(yīng)jsp訪問的異常屬性定義名稱, 默認(rèn)=exception -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 將異常映射到對應(yīng)的 error.jsp 頁面中 -->
<property name="exceptionMappings">
<props>
<!-- 映射數(shù)組越界異常到 error.jsp 頁面中 -->
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
- 在
SpringMVCTestNew控制器中新增測試方法
/**
* 測試SimpleMappingExceptionResolver映射指定異常到對應(yīng)頁面
* 如果頁面?zhèn)鬟f的參數(shù)是20 ,超出數(shù)組邊界, 回拋出數(shù)組越界異常,
* 在springmvc.xml文件中配置映射關(guān)系
* @param i
* @return
*/
@RequestMapping("/testSimpleMappingExceptionResolver")
public String testSimpleMappingExceptionResolver(@RequestParam("i") int i)
{
String[] arr = new String[10];
String val = arr[i];
System.out.println("testSimpleMappingExceptionResolver val = " + val);
return "success";
}
- 在
error.jsp頁面中打印異常
<h4>Error Page</h4>
<p>exception = ${requestScope.ex}</p>
訪問地址: http://localhost:8081/spring-mvc-2/testSimpleMappingExceptionResolver?i=20
error.jsp頁面輸出:
Error Page
exception = java.lang.ArrayIndexOutOfBoundsException: 20



