10、SpringBoot之異常處理
阿新 • • 發佈:2020-08-28
第一種:自定義錯誤頁面
- SpringBoot預設的處理異常的機制:SpringBoot預設的已經提供了一套處理異常的機制。
- 一旦程式中出現了異常SpringBoot會向/error的url傳送請求。
- SpringBoot中提供了一個名為BasicErrorController來處理/error請求,然後跳轉到預設顯示異常的頁面來展示異常資訊。
由於沒有找到/error對映的檔案,所以將錯誤返回到springboot的頁面將異常資訊進行輸出
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Thu Apr 23 23:29:38 CST 2020 There was an unexpected error (type=Internal Server Error, status=500). No message available
如果需要將所有異常統一跳轉到自定義的錯誤頁面,需要在**src/main/resources/templates** 目錄下建立**error.html**頁面。注意:頁面必須叫**error**
當有一個命名為error的錯誤頁面時,出現異常則直接跳到該頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 出現錯誤異常 </body> </html>
缺點:當捕獲到不同的異常想要跳轉至不同頁面是,自定義錯誤頁面沒辦法實現;
第二種:通過@ExceptionHandler註解處理異常
- 修改Controller
- 建立頁面
@ExceptionHandler註解可以做到根據不同異常型別,來跳轉到不同的頁面進行異常資訊的顯示
我們需要在能夠產生異常的方法所在的controller當中再新增一個處理異常的方法
@Controller public class UsersController { /** * 定義一個會報出空指標異常的方法 * @return */ @RequestMapping("showInfo") public String showInfo(){ String str = null; str.length(); return "ok"; } /** * 該方法會處理當前這個controller出現的空指標異常 * @param e * @return */ @ExceptionHandler(value = {java.lang.NullPointerException.class}) public ModelAndView nullpointExceptionHandler(Exception e){ // e物件會接收放錯傳入的異常物件 ModelAndView mv = new ModelAndView(); mv.addObject("err", e); mv.setViewName("error1"); return mv; } }
error1頁面
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
出錯了。。。
<span th:text="${err}"></span>
</body>
</html>
缺點:單用一個@ExceptionHandler註解只能作用他當前的controller進行異常處理,如果其他controller也出現同樣的異常是不會進行處理的,複用性差,這個時候需要@ControllerAdvice結合使用,使異常處理方法可以全域性使用。
第三種:通過@ControllerAdvice與@ExceptionHandler註解處理異常
- 建立全域性異常處理類
Controller
@Controller
public class UsersController {
/**
* 定義一個會報出空指標異常的方法
* @return
*/
@RequestMapping("showInfo")
public String showInfo(){
String str = null;
str.length();
return "ok";
}
/**
* 定義一個會報出算術異常的方法
* @return
*/
@RequestMapping("showInfo2")
public String showInfo2(){
int i = 10/0;
return "ok";
}
}
全域性異常處理類
/**
* 全域性異常處理類
*/
@ControllerAdvice
public class GlobalException {
/**
* 處理空指標異常
* @param e
* @return
*/
@ExceptionHandler(value = {java.lang.NullPointerException.class})
public ModelAndView nullpointExceptionHandler(Exception e){
// e物件會接收放錯傳入的異常物件
ModelAndView mv = new ModelAndView();
mv.addObject("err", e);
mv.setViewName("error1");
return mv;
}
/**
* 處理算術異常
* @param e
* @return
*/
@ExceptionHandler(value = {java.lang.ArithmeticException.class})
public ModelAndView ArithmeticExceptionHandler(Exception e){
// e物件會接收放錯傳入的異常物件
ModelAndView mv = new ModelAndView();
mv.addObject("err", e);
mv.setViewName("error2");
return mv;
}
}
當專案中出現空指標異常都會被該方法攔截並進行處理
全域性異常處理類有個缺點就是會定義特別多的方法來處理異常
第四種,通過SimpleMappingExceptionResolver物件處理異常
SimpleMappingExceptionResolve可以通過一個方法來處理多個不同的異常,並且跳轉到不同的頁面
/**
* 全域性異常
* SimpleMappingExceptionResolver
*/
@Configuration
public class GloballException2 {
/**
* 此方法返回值必須是SimpleMappingExceptionResolver,方法名可以隨意
* @return
*/
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
//簡單對映異常解析,也是可以根據異常型別和需要跳轉檢視做一個對映處理
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
/**
* 引數1:異常型別(全名)
* 引數2:跳轉頁面(檢視)
*/
//這裡只是做,檢視與異常型別的對映,並沒有傳遞異常物件,所以跳轉到對應的檢視後並沒有傳遞異常物件過去
properties.put("java.lang.NullPointerException","error3");
properties.put("java.lang.ArithmeticException","error4");
resolver.setExceptionMappings(properties);
return resolver;
}
}
error3.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
出錯了。。。空指標異常
</body>
</html>
error4.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
<head>
<meta charset="UTF-8">
<title>error2</title>
</head>
<body>
出錯了。。。算術異常
</body>
</html>
缺點:只能做異常和檢視的對映,不能獲取到異常資訊
第五種,通過自定義HandlerExceptionResolver物件處理異常
- 建立全域性異常處理類
全域性異常處理類 GloballException3
/**
* 自定義HandlerExceptionResolve物件處理異常
* 必須要實現HandlerExceptionResolver
*/
@Configuration
public class GloballException3 implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
ModelAndView mv = new ModelAndView();
//判斷不同異常型別,做不同檢視的跳轉
if(e instanceof NullPointerException){
mv.setViewName("error5");
}
if(e instanceof ArithmeticException){
mv.setViewName("error6");
}
//不管跳到哪個檢視,攜帶的異常資訊不變所以不用帶入if判斷裡面
mv.addObject("error", e.toString());
return mv;
}
}
error5.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
<head>
<meta charset="UTF-8">
<title>error5</title>
</head>
<body>
出錯了。。。空指標異常
<span th:text="${error}"></span>
</body>
</html>
error6.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
<head>
<meta charset="UTF-8">
<title>error6</title>
</head>
<body>
出錯了。。。算術異常
<span th:text="${error}"></span>
</body>
</html>