springboot處理異常的5種方式
程序的異常:Throwable
嚴(yán)重錯(cuò)誤問題:Error 我們不處理。這種問題一般都是很嚴(yán)重的,我們一般處理不了,比如說內(nèi)存溢出。
問題:Exception
1.運(yùn)行期問題:RuntimeException 這種問題我們也不處理,因?yàn)槭悄銓懘a的問題,而且這個(gè)問題的出現(xiàn)肯定是我們的代碼不夠嚴(yán)謹(jǐn),需要修正代碼的。
2.編譯期問題:不是RuntimeException的異常 必須進(jìn)行處理的,因?yàn)槟悴惶幚恚幾g就不能通過。
如果程序出現(xiàn)了問題,我們沒有做任何處理,最終JVM會(huì)做出默認(rèn)的處理。
1.把異常的名稱、原因及出現(xiàn)的位置等信息輸出在控制臺(tái)。
2.同時(shí)會(huì)結(jié)束程序。
(但是呢,其余沒有問題的程序就不能繼續(xù)執(zhí)行了)
所以感覺JVM的默認(rèn)處理不夠好,既然不好那我們就自己來處理唄。
1、自定義錯(cuò)誤頁面
SpringBoot默認(rèn)的異常處理機(jī)制:springboot默認(rèn)提供了一套處理異常的機(jī)制。一旦程序出現(xiàn)了異常,SpringBoot會(huì)向/error的url發(fā)送請(qǐng)求。在springboot中提供了一個(gè)叫BasicErrorController 來處理/error 請(qǐng)求,然后跳轉(zhuǎn)到默認(rèn)顯示異常的頁面來展示異常信息。
如 果 我 們 需 要 將 所 有 的 異 常 統(tǒng)一 跳 轉(zhuǎn) 到 自 定 義 的 錯(cuò) 誤 頁 面 , 需 要 再
src/main/resources/templates 目錄下創(chuàng)建 error.html 頁面。注意:名稱必須叫 error
還可以在src/main/resources/templates/error目錄下編寫狀態(tài)碼.html文件,會(huì)默認(rèn)先從這里找,找不到再找src/main/resources/templates下的error.html
2、@ExceptionHandle 注解處理異常
上一種方法不管發(fā)生什么異常,都只能跳轉(zhuǎn)到一個(gè)頁面,顆粒度太大,這一種方式可以實(shí)現(xiàn)對(duì)不同的異常做不同的處理。
@RequestMapping @Controller public class ExceptionController { ? ? @PostMapping("/exception") ? ? public String hello(){ ? ? ? ? //int i = 1/0; ? ? ? ? return "index"; ? ? } ? ? /** ? ? ?* 該方法返回ModelAndView:目的是為了可以讓我們封裝視圖和錯(cuò)誤信息 ? ? ?* @param e 參數(shù) Exception e:會(huì)將產(chǎn)生異常對(duì)象注入到方法中 ? ? ?* @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)點(diǎn):可以自定義存儲(chǔ)異常信息的key,和跳轉(zhuǎn)視圖的名稱。
缺點(diǎn):需要編寫大量的異常方法,不能跨controller,如果兩個(gè)controller中出現(xiàn)同樣的異常,需要重新編寫異常處理方法。
3、@ControllerAdvice+@ExceptionHandler 注解處理異常
上一種方式必須要在每一個(gè)Controler里面重復(fù)寫異常處理代碼,代碼復(fù)用性太差,這一種方法可以實(shí)現(xiàn)異常的全局處理。需要?jiǎng)?chuàng)建一個(gè)能夠處理異常的全局異常類。在該類上需要添加@ControllerAdvice 注解
/** ?* 全局異常處理類 ?*/ @ControllerAdvice public class GlobalController { ? ? /** ? ? ?* 該方法返回ModelAndView:目的是為了可以讓我們封裝視圖和錯(cuò)誤信息 ? ? ?* @param e 參數(shù) Exception e:會(huì)將產(chǎn)生異常對(duì)象注入到方法中 ? ? ?* @return ? ? ?*/ ? ? //攔截的異常可以寫Exception ? ? @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; ? ? } }
缺點(diǎn):編寫大量的異常處理方法,代碼冗余。
4、配置 SimpleMappingExceptionResolver 處理異常
上一種方式,每處理一種異常就要寫一個(gè)處理方法,如果有很多異常需要處理,寫起來會(huì)很麻煩,這一種方式可以很好的解決這種問題,需要在全局異常類中添加一個(gè)方法完成異常的統(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; ? ? } }
缺點(diǎn):不顯示具體異常信息
5、自定義 HandlerExceptionResolver 類處理異常
上一種方式不能在跳轉(zhuǎn)頁面的同時(shí)攜帶異常信息,這樣不利于排錯(cuò),當(dāng)前這種方式可以解決上述問題,我們需 要 在全局異常處理類中實(shí)現(xiàn)HandlerExceptionResolver 接口。
/** ?* 通過實(shí)現(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,"商品價(jià)格不能為空"), ? ? ; ? ? 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; //時(shí)間戳 ? ? 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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot異常處理之異常顯示的頁面問題
- SpringBoot優(yōu)雅地實(shí)現(xiàn)全局異常處理的方法詳解
- Springboot項(xiàng)目異常處理及返回結(jié)果統(tǒng)一
- 如何在SpringBoot項(xiàng)目里進(jìn)行統(tǒng)一異常處理
- SpringBoot接口如何統(tǒng)一異常處理
- springboot?全局異常處理和統(tǒng)一響應(yīng)對(duì)象的處理方式
- SpringBoot詳解實(shí)現(xiàn)自定義異常處理頁面方法
- SpringBoot中異常處理實(shí)戰(zhàn)記錄
- SpringBoot錯(cuò)誤處理流程深入詳解
相關(guān)文章
詳解Java的Hibernate框架中的緩存與二級(jí)緩存
這篇文章主要介紹了Java的Hibernate框架中的緩存與二級(jí)緩存,Hibernate是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12Java中使用同步回調(diào)和異步回調(diào)的示例詳解
這篇文章主要介紹了Java中使用同步回調(diào)和異步回調(diào)的相關(guān)資料,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04java連接池Druid連接回收DestroyConnectionThread&DestroyTask
這篇文章主要為大家介紹了java連接池Druid連接回收DestroyConnectionThread&DestroyTask示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09java如何讀取某個(gè)文件夾中的全部文件(包括子文件夾)
這篇文章主要介紹了java如何讀取某個(gè)文件夾中的全部文件(包括子文件夾),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12springboot實(shí)現(xiàn)文件上傳步驟解析
這篇文章主要介紹了springboot實(shí)現(xiàn)文件上傳步驟解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12Java 使用keytool創(chuàng)建CA證書的操作
這篇文章主要介紹了Java 使用keytool創(chuàng)建CA證書的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01