springboot處理異常的5種方式
程序的異常:Throwable
嚴重錯誤問題:Error 我們不處理。這種問題一般都是很嚴重的,我們一般處理不了,比如說內(nèi)存溢出。
問題:Exception
1.運行期問題:RuntimeException 這種問題我們也不處理,因為是你寫代碼的問題,而且這個問題的出現(xiàn)肯定是我們的代碼不夠嚴謹,需要修正代碼的。
2.編譯期問題:不是RuntimeException的異常 必須進行處理的,因為你不處理,編譯就不能通過。
如果程序出現(xiàn)了問題,我們沒有做任何處理,最終JVM會做出默認的處理。
1.把異常的名稱、原因及出現(xiàn)的位置等信息輸出在控制臺。
2.同時會結(jié)束程序。
(但是呢,其余沒有問題的程序就不能繼續(xù)執(zhí)行了)
所以感覺JVM的默認處理不夠好,既然不好那我們就自己來處理唄。
1、自定義錯誤頁面
SpringBoot默認的異常處理機制:springboot默認提供了一套處理異常的機制。一旦程序出現(xiàn)了異常,SpringBoot會向/error的url發(fā)送請求。在springboot中提供了一個叫BasicErrorController 來處理/error 請求,然后跳轉(zhuǎn)到默認顯示異常的頁面來展示異常信息。
如 果 我 們 需 要 將 所 有 的 異 常 統(tǒng)一 跳 轉(zhuǎn) 到 自 定 義 的 錯 誤 頁 面 , 需 要 再
src/main/resources/templates 目錄下創(chuàng)建 error.html 頁面。注意:名稱必須叫 error
還可以在src/main/resources/templates/error目錄下編寫狀態(tài)碼.html文件,會默認先從這里找,找不到再找src/main/resources/templates下的error.html
2、@ExceptionHandle 注解處理異常
上一種方法不管發(fā)生什么異常,都只能跳轉(zhuǎn)到一個頁面,顆粒度太大,這一種方式可以實現(xiàn)對不同的異常做不同的處理。
@RequestMapping
@Controller
public class ExceptionController {
? ? @PostMapping("/exception")
? ? public String hello(){
? ? ? ? //int i = 1/0;
? ? ? ? return "index";
? ? }
? ? /**
? ? ?* 該方法返回ModelAndView:目的是為了可以讓我們封裝視圖和錯誤信息
? ? ?* @param e 參數(shù) Exception e:會將產(chǎn)生異常對象注入到方法中
? ? ?* @return
? ? ?*/
? ? @ExceptionHandler(value = {java.lang.ArithmeticException.class})
? ? public ModelAndView arithmeticExceptionHandler(Exception e){
? ? ? ? ModelAndView mv = new ModelAndView();
? ? ? ? mv.addObject("errorMsg",e);
? ? ? ? mv.setViewName("error");
? ? ? ? return mv;
? ? }
}優(yōu)點:可以自定義存儲異常信息的key,和跳轉(zhuǎn)視圖的名稱。
缺點:需要編寫大量的異常方法,不能跨controller,如果兩個controller中出現(xiàn)同樣的異常,需要重新編寫異常處理方法。
3、@ControllerAdvice+@ExceptionHandler 注解處理異常
上一種方式必須要在每一個Controler里面重復(fù)寫異常處理代碼,代碼復(fù)用性太差,這一種方法可以實現(xiàn)異常的全局處理。需要創(chuàng)建一個能夠處理異常的全局異常類。在該類上需要添加@ControllerAdvice 注解
/**
?* 全局異常處理類
?*/
@ControllerAdvice
public class GlobalController {
? ? /**
? ? ?* 該方法返回ModelAndView:目的是為了可以讓我們封裝視圖和錯誤信息
? ? ?* @param e 參數(shù) Exception e:會將產(chǎn)生異常對象注入到方法中
? ? ?* @return
? ? ?*/
? ? //攔截的異??梢詫慐xception
? ? @ExceptionHandler(value = {java.lang.ArithmeticException.class})
? ? public ModelAndView arithmeticExceptionHandler(Exception e){
? ? ? ? ModelAndView mv = new ModelAndView();
? ? ? ? mv.addObject("errorMsg",e+"controllerAdvice");
? ? ? ? mv.setViewName("error");
? ? ? ? return mv;
? ? }
}缺點:編寫大量的異常處理方法,代碼冗余。
4、配置 SimpleMappingExceptionResolver 處理異常
上一種方式,每處理一種異常就要寫一個處理方法,如果有很多異常需要處理,寫起來會很麻煩,這一種方式可以很好的解決這種問題,需要在全局異常類中添加一個方法完成異常的統(tǒng)一處理。
/**
?* 通過 SimpleMappingExceptionResolver 做全局異常處理
?*/
@Configuration
public class GlobalException {
? ? /**
? ? ?* 該方法必須要有返回值。返回值類型必須是: SimpleMappingExceptionResolver
? ? ?* @return
? ? ?*/
? ? @Bean
? ? public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
? ? ? ? SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
? ? ? ? Properties prop = new Properties();
? ? ? ? //參數(shù)1:異常的全類名 ?參數(shù)2:視圖的名字
? ? ? ? prop.setProperty("java.lang.ArithmeticException","error");
? ? ? ? prop.setProperty("java.lang.NullPointerException","error");
? ? ? ? //設(shè)置異常與視圖的映射信息
? ? ? ? resolver.setExceptionMappings(prop);
? ? ? ? return resolver;
? ? }
}缺點:不顯示具體異常信息
5、自定義 HandlerExceptionResolver 類處理異常
上一種方式不能在跳轉(zhuǎn)頁面的同時攜帶異常信息,這樣不利于排錯,當前這種方式可以解決上述問題,我們需 要 在全局異常處理類中實現(xiàn)HandlerExceptionResolver 接口。
/**
?* 通過實現(xiàn) HandlerExceptionResolver 接口做全局異常處理
?*/
@Configuration
public class GlobalException implements HandlerExceptionResolver {
? ? @Override
? ? public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
? ? ? ? ModelAndView mv = new ModelAndView();
? ? ? ? //判斷不同的異常類型跳轉(zhuǎn)不同視圖
? ? ? ? if(ex instanceof ArithmeticException){
? ? ? ? ? ? mv.setViewName("error");
? ? ? ? }
? ? ? ? if(ex instanceof NullPointerException){
? ? ? ? ? ? mv.setViewName("error");
? ? ? ? }
? ? ? ? mv.addObject("errorMsg",ex.toString());
? ? ? ? return mv;
? ? }
}通用異常處理:
1、自定義異常枚舉類
public enum ExceptionEnum {
? ? //枚舉常量
? ? PRICE_CANNOT_BE_NULL(500,"商品價格不能為空"),
? ? ;
? ? private int code; ?//狀態(tài)碼
? ? private String msg; //異常信息
? ? ExceptionEnum() {
? ? }
? ? ExceptionEnum(int code, String msg) {
? ? ? ? this.code = code;
? ? ? ? this.msg = msg;
? ? }
? ? public int getCode() {
? ? ? ? return code;
? ? }
? ? public void setCode(int code) {
? ? ? ? this.code = code;
? ? }
? ? public String getMsg() {
? ? ? ? return msg;
? ? }
? ? public void setMsg(String msg) {
? ? ? ? this.msg = msg;
? ? }
}2、自定義異常類
/**
?* 自定義異常類,繼承RuntimeException
?*/
public class MyException extends RuntimeException{
? ? private ExceptionEnum exceptionEnum;
? ? public MyException() {
? ? }
? ? public MyException(ExceptionEnum exceptionEnum) {
? ? ? ? this.exceptionEnum = exceptionEnum;
? ? }
? ? public ExceptionEnum getExceptionEnum() {
? ? ? ? return exceptionEnum;
? ? }
? ? public void setExceptionEnum(ExceptionEnum exceptionEnum) {
? ? ? ? this.exceptionEnum = exceptionEnum;
? ? }
? ? @Override
? ? public String toString() {
? ? ? ? return "MyException{" +
? ? ? ? ? ? ? ? "exceptionEnum=" + exceptionEnum +
? ? ? ? ? ? ? ? '}';
? ? }
}3、自定義異常結(jié)果處理類
/**
?* 自定義異常結(jié)果處理類
?*/
public class ResultException {
? ? private Integer statusCode; //狀態(tài)碼
? ? private String message; ? ? //異常信息
? ? private Long timeStamp; //時間戳
? ? public ResultException() {
? ? }
? ? public ResultException(ExceptionEnum em){
? ? ? ? this.statusCode = em.getCode();
? ? ? ? this.message = em.getMsg();
? ? ? ? this.timeStamp = System.currentTimeMillis();
? ? }
? ? public Integer getStatusCode() {
? ? ? ? return statusCode;
? ? }
? ? public void setStatusCode(Integer statusCode) {
? ? ? ? this.statusCode = statusCode;
? ? }
? ? public String getMessage() {
? ? ? ? return message;
? ? }
? ? public void setMessage(String message) {
? ? ? ? this.message = message;
? ? }
? ? public Long getTimeStamp() {
? ? ? ? return timeStamp;
? ? }
? ? public void setTimeStamp(Long timeStamp) {
? ? ? ? this.timeStamp = timeStamp;
? ? }
? ? @Override
? ? public String toString() {
? ? ? ? return "ResultException{" +
? ? ? ? ? ? ? ? "statusCode=" + statusCode +
? ? ? ? ? ? ? ? ", message='" + message + '\'' +
? ? ? ? ? ? ? ? ", timeStamp=" + timeStamp +
? ? ? ? ? ? ? ? '}';
? ? }
}4、全局異常處理
/**
?* ?@ControllerAdvice + @ExceptionHandler +自定義異常 ?來做全局異常處理
?*/
@ControllerAdvice
public class GlobalException {
? ? /**
? ? ?* 攔截自定義異常MyException
? ? ?* @param e
? ? ?* @return
? ? ?*/
// ? ?@ExceptionHandler(MyException.class)
// ? ?public @ResponseBody ResultException handlerRuntimeException(MyException e){
// ? ? ? ?ExceptionEnum exceptionEnum = e.getExceptionEnum();
// ? ? ? ?ResultException res = new ResultException(exceptionEnum);
// ? ? ? ?
到此這篇關(guān)于springboot處理異常的5種方式的文章就介紹到這了,更多相關(guān)springboot處理異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
HttpServletRequest的getParameter()的坑及解決
這篇文章主要介紹了HttpServletRequest的getParameter()的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Java輸入三個整數(shù)并把他們由小到大輸出(x,y,z)
這篇文章主要介紹了輸入三個整數(shù)x,y,z,請把這三個數(shù)由小到大輸出,需要的朋友可以參考下2017-02-02
SpringBoot使用WebSocket實現(xiàn)向前端推送消息功能
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議,它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端,本文給大家介紹了SpringBoot使用WebSocket實現(xiàn)向前端推送消息功能,需要的朋友可以參考下2024-05-05
給Java菜鳥的一些建議_關(guān)于Java知識點歸納(J2EE and Web 部分)
下面小編就為大家?guī)硪黄oJava菜鳥的一些建議_關(guān)于Java知識點歸納(J2EE and Web 部分)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05

