Springboot異常錯(cuò)誤處理解決方案詳解
1.在有模板引擎的情況下:
springboot會(huì)默認(rèn)找 templates/error/錯(cuò)誤狀態(tài)碼.html,所以我們要定制化錯(cuò)誤頁(yè)面就可以到templates/error下創(chuàng)建一個(gè)【對(duì)應(yīng)錯(cuò)誤狀態(tài)碼.html】html文件,當(dāng)發(fā)生此狀態(tài)碼的錯(cuò)誤springboot就會(huì)來(lái)到對(duì)應(yīng)的頁(yè)面。
同時(shí)如果我們想讓400-499之間的錯(cuò)誤都去同一個(gè)錯(cuò)誤頁(yè)面,那我們可以在templates/error下創(chuàng)建一個(gè)4xx.html。同理500-599的錯(cuò)誤可以用5xx.html。

注意:springboot會(huì)優(yōu)先匹配具體的【錯(cuò)誤狀態(tài)碼.html】,然后再匹配4xx,5xx的。例如:發(fā)生了404錯(cuò)誤,springboot優(yōu)先到templates/error下找404.html,如果沒(méi)有404.html,再找有沒(méi)有4xx.html,有的話就會(huì)使用4xx.html。
在錯(cuò)誤頁(yè)面我們能夠獲取到的信息:
- timestamp:時(shí)間戳
- status:狀態(tài)碼
- error:錯(cuò)誤提示
- exception:異常對(duì)象 springboot2.1.6在頁(yè)面獲取異常對(duì)象要現(xiàn)在全局配置文件中加入:server.error.include-exception=true
- message:異常消息
- errors:JSR數(shù)據(jù)校驗(yàn)的錯(cuò)誤
2.在沒(méi)有模板引擎(模板引擎找不到這個(gè)錯(cuò)誤頁(yè)面)的情況下,springboot會(huì)到靜態(tài)資源文件夾下的error包下找。
3.以上都沒(méi)有找到錯(cuò)誤頁(yè)面,就默認(rèn)用springboot默認(rèn)的錯(cuò)誤提示頁(yè)面
錯(cuò)誤異常處理——自定義響應(yīng)json數(shù)據(jù)
上邊的錯(cuò)誤處理中,如果是瀏覽器訪問(wèn)可以響應(yīng)我們自己定制的錯(cuò)誤頁(yè)面,但是如果是其他客戶端訪問(wèn),則只會(huì)響應(yīng)固定的json數(shù)據(jù),如下圖所示:

下邊講解三個(gè)異常處理返回自定義json數(shù)據(jù)的方式
首先編寫(xiě)一個(gè)自定義異常類(lèi)
public class UserNotExitException extends RuntimeException {
public UserNotExitException() {
super("用戶不存在");
}
}
方式一:
在異常處理器類(lèi)中,通過(guò)map封裝我們自己的json數(shù)據(jù),然后將map返回。
@ControllerAdvice
public class MyExceptionHandler {
@ResponseBody
@ExceptionHandler(UserNotExitException.class)
public Map<String,Object> userNotExitExceptionHandler(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","user.notexit");
map.put("message",e.getMessage());
return map;
}
}
@ControllerAdvice:表明這是一個(gè)全局異常處理類(lèi)
@ExceptionHandler(UserNotExitException.class):表明標(biāo)注的此方法用于處理UserNotExitException異常。
@ResponseBody:將返回結(jié)果封裝為json
3.結(jié)果
不管瀏覽器還是其他客戶端發(fā)生該異常都統(tǒng)一得到下圖的響應(yīng)

方式二:轉(zhuǎn)發(fā)到/error,進(jìn)行自適應(yīng)響應(yīng)效果處理
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(UserNotExitException.class)
public String userNotExitExceptionHandler(Exception e, HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
request.setAttribute("javax.servlet.error.status_code",500);
map.put("code","user.notexit");
map.put("message","用戶出錯(cuò)了");
return "forward:/error";
}
}
將響應(yīng)轉(zhuǎn)發(fā)到 /error,讓springboot幫我們生成自適應(yīng)效果。但是必須注意,一定要設(shè)置錯(cuò)誤狀態(tài)碼(如代碼中標(biāo)黃色的那一句代碼)。不設(shè)置的話springboot就不會(huì)進(jìn)入定制錯(cuò)誤頁(yè)面的解析流程。設(shè)置了之后springboot就會(huì)到templates/error/錯(cuò)誤狀態(tài)碼.html頁(yè)面處理。
注意:此方式瀏覽器訪問(wèn)發(fā)生錯(cuò)誤不再響應(yīng)的是json數(shù)據(jù)了,而是對(duì)于的錯(cuò)誤響應(yīng)網(wǎng)頁(yè)。

其他客戶端訪問(wèn)響應(yīng)的是json數(shù)據(jù),但是響應(yīng)的json數(shù)據(jù)中沒(méi)有我們map中put的數(shù)據(jù)。

方式三:通過(guò)DefaultErrorAttribute
1.在異常處理器類(lèi)中將響應(yīng)的json數(shù)據(jù)封裝到map中,然后再將map放到請(qǐng)求域中
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(UserNotExitException.class)
public String userNotExitExceptionHandler(Exception e, HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
request.setAttribute("javax.servlet.error.status_code",500);
map.put("code","user.notexit");
map.put("message","用戶出錯(cuò)了");
request.setAttribute("ext",map);
return "forward:/error";
}
}
2.編寫(xiě)錯(cuò)誤屬性類(lèi):新建一個(gè)類(lèi)繼承DefaultErrorAttribute類(lèi),并重寫(xiě)其中的getErrorAttributes方法
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
map.put("company","atguigu");
Map<String, Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", 0);
map.put("ext",ext);
return map;
}
}
注意:
(1).必須將錯(cuò)誤屬性類(lèi)添加到spring容器中。
(2).第7行標(biāo)黃那段代碼的作用是獲取異常處理類(lèi)中的map。其中最后的參數(shù)0,是從request域中取出數(shù)據(jù)“ext”。若要從session域中取數(shù)據(jù),則將該參數(shù)設(shè)置為1.(0是從request域獲取數(shù)據(jù),1是從session域中獲取數(shù)據(jù))
(3).錯(cuò)誤屬性類(lèi)中返回的map中的所有內(nèi)容,頁(yè)面都可以獲取到。
總結(jié):
此方式最好,當(dāng)瀏覽器訪問(wèn)發(fā)生錯(cuò)誤時(shí),會(huì)響應(yīng)對(duì)應(yīng)的錯(cuò)誤響應(yīng)頁(yè)面,當(dāng)其他客戶端訪問(wèn)發(fā)生錯(cuò)誤時(shí)也會(huì)響應(yīng)我們定制的json數(shù)據(jù)。
瀏覽器響應(yīng):

其他客戶端響應(yīng):

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot錯(cuò)誤處理流程深入詳解
- SpringBoot2.1.4中的錯(cuò)誤處理機(jī)制
- Springboot實(shí)現(xiàn)自定義錯(cuò)誤頁(yè)面的方法(錯(cuò)誤處理機(jī)制)
- Springboot錯(cuò)誤處理機(jī)制實(shí)現(xiàn)原理解析
- SpringBoot錯(cuò)誤處理機(jī)制以及自定義異常處理詳解
- SpringBoot 錯(cuò)誤處理機(jī)制與自定義錯(cuò)誤處理實(shí)現(xiàn)詳解
- springboot 錯(cuò)誤處理小結(jié)
- SpringBoot自定義錯(cuò)誤處理邏輯詳解
相關(guān)文章
面試初級(jí)Java開(kāi)發(fā)問(wèn)到Arrays
這篇文章主要介紹了Java Arrays工具類(lèi)用法,結(jié)合實(shí)例形式分析了java Arrays工具類(lèi)針對(duì)數(shù)組元素修改、復(fù)制、排序等操作使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2021-07-07
java網(wǎng)絡(luò)編程中向指定URL發(fā)送GET POST請(qǐng)求示例
這篇文章主要介紹了java向指定URL發(fā)送GET POST請(qǐng)求示例,學(xué)習(xí)JAVA網(wǎng)絡(luò)編程一定會(huì)用到的,大家參考使用吧2013-11-11
spring-boot 如何實(shí)現(xiàn)單次執(zhí)行程序
這篇文章主要介紹了spring-boot 實(shí)現(xiàn)單次執(zhí)行程序方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
使用Java實(shí)現(xiàn)簡(jiǎn)單搭建內(nèi)網(wǎng)穿透
內(nèi)網(wǎng)穿透是一種網(wǎng)絡(luò)技術(shù),適用于需要遠(yuǎn)程訪問(wèn)本地部署服務(wù)的場(chǎng)景,本文主要為大家介紹了如何使用Java實(shí)現(xiàn)簡(jiǎn)單搭建內(nèi)網(wǎng)穿透,感興趣的可以了解下2024-02-02
淺談ArrayList和LinkedList到底誰(shuí)更快
今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著ArrayList和LinkedList到底誰(shuí)更快展開(kāi),文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
Java基礎(chǔ)之線程鎖相關(guān)知識(shí)總結(jié)
今天給大家?guī)?lái)的是關(guān)于Java線程的相關(guān)知識(shí),文章圍繞著Java線程鎖展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
Java經(jīng)緯度小數(shù)與度分秒相互轉(zhuǎn)換工具類(lèi)示例詳解
這篇文章主要介紹了Java經(jīng)緯度小數(shù)與度分秒相互轉(zhuǎn)換工具類(lèi),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
java可變參數(shù)(不定向參數(shù))的作用與實(shí)例
這篇文章主要給大家介紹了關(guān)于java可變參數(shù)(不定向參數(shù))的作用與實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

