異常處理器
異常處理器快速入門
程序開(kāi)發(fā)過(guò)程中不可避免的會(huì)遇到異?,F(xiàn)象
出現(xiàn)異?,F(xiàn)象的常見(jiàn)位置與常見(jiàn)原因如下:
框架內(nèi)部拋出的異常:因使用不規(guī)范導(dǎo)致
數(shù)據(jù)層拋出的異常:因外部服務(wù)器故障導(dǎo)致(例如:服務(wù)器訪問(wèn)超時(shí))
業(yè)務(wù)層拋出的異常:因業(yè)務(wù)邏輯書(shū)寫(xiě)錯(cuò)誤導(dǎo)致(例如:遍歷業(yè)務(wù)書(shū)寫(xiě)操作,導(dǎo)致索引異常等)
表現(xiàn)層拋出的異常:因數(shù)據(jù)收集、校驗(yàn)等規(guī)則導(dǎo)致(例如:不匹配的數(shù)據(jù)類型間導(dǎo)致異常)
工具類拋出的異常:因工具類書(shū)寫(xiě)不嚴(yán)謹(jǐn)不夠健壯導(dǎo)致(例如:必要釋放的連接長(zhǎng)期未釋放等)
各個(gè)層級(jí)均出現(xiàn)異常,異常處理代碼書(shū)寫(xiě)在哪一層都是不合適的
當(dāng)出現(xiàn)異常, 我們讓每一層的異常都不處理往上一層拋出, 所有的異常均拋出到表現(xiàn)層進(jìn)行處理
表現(xiàn)層處理異常,如果每個(gè)方法中都單獨(dú)書(shū)寫(xiě)try…catch…,代碼書(shū)寫(xiě)量巨大且意義不強(qiáng)
采用AOP思想解決
SpringMVC提供了異常處理器:
集中的、統(tǒng)一的處理項(xiàng)目中出現(xiàn)的異常; 既然最終異常是在表現(xiàn)層進(jìn)行統(tǒng)一處理, 那么我們異常處理器的類也需要寫(xiě)在表現(xiàn)層controller包下
@RestControllerAdvice類注解
定義在Rest風(fēng)格開(kāi)發(fā)的控制器增強(qiáng)類定義上方, 為Rest風(fēng)格開(kāi)發(fā)的控制器類做增強(qiáng), 此注解自帶@ResponseBody注解與@Component注解,具備對(duì)應(yīng)的功能
@ExceptionHandler方法注解:
專用于異常處理的控制器方法上方, 用于設(shè)置指定異常的處理方案,功能等同于控制器方法,出現(xiàn)異常后終止原始控制器執(zhí)行,并轉(zhuǎn)入當(dāng)前方法執(zhí)行; 此類方法可以根據(jù)處理的異常不同,制作多個(gè)方法分別處理對(duì)應(yīng)的異常
@RestControllerAdvice // 聲明該類是用來(lái)做異常處理的
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class) // 聲明該方法是攔截所有異常
public Result doException(Exception ex) {
// 返回異常提示
return new Result(666, null, "出現(xiàn)異常");
}
}
項(xiàng)目異常處理
項(xiàng)目中的異常不能和上面的處理方式一樣
項(xiàng)目異常分類:
業(yè)務(wù)異常(BusinessException)
- 規(guī)范的用戶行為產(chǎn)生的異常
- 不規(guī)范的用戶行為操作產(chǎn)生的異常
系統(tǒng)異常(SystemException)
- 項(xiàng)目運(yùn)行過(guò)程中可預(yù)計(jì)且無(wú)法避免的異常, 例如服務(wù)器斷電死機(jī)等
其他異常(Exception)
- 編程人員未預(yù)期到的異常
項(xiàng)目異常處理方案:
針對(duì)業(yè)務(wù)異常(BusinessException): 發(fā)送對(duì)應(yīng)消息傳遞給用戶,提醒規(guī)范操作
針對(duì)系統(tǒng)異常(SystemException):
- 發(fā)送固定消息傳遞給用戶,安撫用戶
- 發(fā)送特定消息給運(yùn)維人員,提醒維護(hù)
- 記錄日志
針對(duì)其他異常(Exception):
- 發(fā)送固定消息傳遞給用戶,安撫用戶
- 發(fā)送特定消息給編程人員,提醒維護(hù)(納入預(yù)期范圍內(nèi))
- 記錄日志
使用步驟:
- 創(chuàng)建一個(gè)exception包, 在該包下分別創(chuàng)建業(yè)務(wù)異常類和系統(tǒng)異常類:
創(chuàng)建業(yè)務(wù)異常類BusinessException繼承自RuntimeException類
public class BusinessException extends RuntimeException {
// 添加一個(gè)編號(hào)用于識(shí)別異常
private Integer code;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
創(chuàng)建系統(tǒng)異常SystemException繼承自RuntimeException類
public class SystemException extends RuntimeException{
// 添加一個(gè)編號(hào)用于識(shí)別異常
private Integer code;
public SystemException(Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
- 自定義異常編碼(持續(xù)補(bǔ)充)
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer SELECT_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer SELECT_ERR = 20040;
public static final Integer SYSTEM_ERROR = 50001; // 系統(tǒng)異常
public static final Integer SYSTEM_TIMEOUT_ERROR = 50002; // 請(qǐng)求超時(shí)
public static final Integer SYSTEM_UNKNOW_ERROR = 59999; // 系統(tǒng)未知異常
public static final Integer BUSINESS_ERROR = 60001; // 業(yè)務(wù)異常
}
- 觸發(fā)自定義異常: 將可能出現(xiàn)的轉(zhuǎn)換為自定義異常
示例: 使用系統(tǒng)異常文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-431093.html
@GetMapping("/{id}")
public Result selectById(@PathVariable Integer id) {
try {
int i = 1/0;
} catch (Exception e) {
throw new SystemException(Code.SYSTEM_TIMEOUT_ERROR, "服務(wù)器訪問(wèn)超時(shí), 請(qǐng)稍后重試", e);
}
Book book = bookService.selectById(id);
boolean flag = book != null;
Integer code = flag ? Code.SELECT_OK: Code.SELECT_ERR;
String msg = flag ? "": "數(shù)據(jù)查詢失敗, 請(qǐng)重試!";
return new Result(code, book, msg);
}
示例: 使用業(yè)務(wù)異常文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-431093.html
@GetMapping("/{id}")
public Result selectById(@PathVariable Integer id) {
if (id < 0) {
throw new BusinessException(Code.BUSINESS_ERROR, "請(qǐng)進(jìn)行合法的操作");
}
Book book = bookService.selectById(id);
boolean flag = book != null;
Integer code = flag ? Code.SELECT_OK: Code.SELECT_ERR;
String msg = flag ? "": "數(shù)據(jù)查詢失敗, 請(qǐng)重試!";
return new Result(code, book, msg);
}
- 處理器攔截系統(tǒng)異常和業(yè)務(wù)異常并處理
@RestControllerAdvice // 聲明該類是用來(lái)做異常處理的
public class ProjectExceptionAdvice {
@ExceptionHandler(SystemException.class) // 攔截系統(tǒng)異常
public Result doSystemException(SystemException e) {
// 記錄日志...
// 發(fā)送消息給運(yùn)維...
// 發(fā)送郵件給開(kāi)發(fā)人員..
// 返回異常提示
return new Result(e.getCode(), null, e.getMessage());
}
@ExceptionHandler(BusinessException.class) // 攔截業(yè)務(wù)異常
public Result doBusinessException(BusinessException e) {
// 返回異常提示
return new Result(e.getCode(), null, e.getMessage());
}
@ExceptionHandler(Exception.class) // 其他異常: 攔截所有的異常
public Result doException(Exception ex) {
// 記錄日志...
// 發(fā)送消息給運(yùn)維...
// 發(fā)送郵件給開(kāi)發(fā)人員..
// 返回異常提示
return new Result(Code.SYSTEM_UNKNOW_ERROR, null, "系統(tǒng)繁忙請(qǐng)稍后再試");
}
}
到了這里,關(guān)于SSM整合(三) | 異常處理器 - 項(xiàng)目異常的處理方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!