1、 SpringBoot異常的設(shè)計(jì)的原理
Spring Boot中,支持RestControllerAdvice統(tǒng)一處理異常,在一個(gè)請(qǐng)求響應(yīng)周期當(dāng)中,如果Controller,Service,Repository出現(xiàn)任何異常,都會(huì)被RestControllerAdvice機(jī)制所捕獲進(jìn)行統(tǒng)一處理。進(jìn)行統(tǒng)一異常處理的目的也就是為了將千奇百怪的異常信息轉(zhuǎn)換成用戶可識(shí)別的錯(cuò)誤信息
統(tǒng)一異常攔截器
@RestControllerAdvice
@Slf4jpublic class GlobalExceptionTranslator { }
系統(tǒng)中的兩類異常處理
第一類:業(yè)務(wù)自定義的異常,遇到這種異常,攔截器記錄后,將業(yè)務(wù)異常自己的信息拋出。
@ExceptionHandler(BusinessException.class)
public JSONObject handleError(BusinessException e) {
? ? log.error("Business Exception {}", getStackTraceAsString(e));
? ? return error(e);
}
第二類:未定義異常,攔截器負(fù)責(zé)統(tǒng)一屏蔽原來(lái)的異常信息,轉(zhuǎn)為服務(wù)器內(nèi)部異常拋出。
@ExceptionHandler(Throwable.class)
public JSONObject handleError(Throwable undefined) {
? ? log.error("Internal Server Error {}", getStackTraceAsString(undefined));
? ? return error(new BusinessException(FAILURE));
}
調(diào)用者收到error的結(jié)果后,直接顯示msg內(nèi)容為用戶可見(jiàn)的錯(cuò)誤信息即可。
如何自定義一個(gè)業(yè)務(wù)異常
在業(yè)務(wù)開(kāi)發(fā)中,通常無(wú)需進(jìn)行Try catch處理,有業(yè)務(wù)異常直接拋出即可。如果需要定義一類通用的異常,則需要在自己業(yè)務(wù)模塊下新建異常類,繼承于 BusinessException
public class PaymentException extends BusinessException {
? ? //重寫(xiě)構(gòu)造函數(shù),從而定義該自定義異常的用戶可見(jiàn)的錯(cuò)誤信息
? ? public PaymentException() {
? ? ? ? super("支付失敗");
? ? }
}
如何自定義一個(gè)框架級(jí)異常
在系統(tǒng)框架層面,已經(jīng)預(yù)定義了一些常見(jiàn)的異常類,如:
類名
定義
預(yù)置錯(cuò)誤信息
PermissionDenyException
用戶訪問(wèn)未授權(quán)的內(nèi)容
權(quán)限不足
ServiceNotFoundException
調(diào)用微服務(wù)失敗
調(diào)用相關(guān)服務(wù)失敗
其他異常
…
…
在定義框架級(jí)異常時(shí),除了需要編寫(xiě)異常類之外,如需要前端根據(jù)error CODE做對(duì)應(yīng)的處理,就可以在ResultCode中增加定義。示例如下:
@Getter
@AllArgsConstructor
public enum ResultCode {
? ? /**
? ? * 操作成功
? ? */
? ? SUCCESS(HTTP_OK, "操作成功"),
? ? /**
? ? * 因程序內(nèi)部錯(cuò)誤操作失敗(如不指定,則默認(rèn)這個(gè)異常)
? ? */
? ? FAILURE(HTTP_INTERNAL_ERROR, "系統(tǒng)運(yùn)行異常,請(qǐng)聯(lián)系管理員"),
? ? /**
? ? * 用戶訪問(wèn)未授權(quán)的內(nèi)容
? ? */
? ? UN_AUTHORIZED(HTTP_UNAUTHORIZED, "權(quán)限不足"),
? ? /**
? ? * 調(diào)用微服務(wù)失敗
? ? */
? ? NOT_FOUND(HTTP_NOT_FOUND, "調(diào)用相關(guān)服務(wù)失敗");
? ? final int code;
? ? final String msg;
}
一個(gè)框架級(jí)異常的實(shí)現(xiàn)類
public class PermissionDenyException extends BusinessException {
? ? public PermissionDenyException() {
? ? ? ? super(UN_AUTHORIZED);
? ? }
}
如需要框架對(duì)該異常定義統(tǒng)一的策略,則需要在GlobalExceptionTranslator實(shí)現(xiàn)該策略,示例如下:
public class GlobalExceptionTranslator {?
? ? @ExceptionHandler(NewGlobalException.class)
? ? public JSONObject handleError(NewGlobalException e) {
? ? ? ? // 這里可以實(shí)現(xiàn)自定義的異常策略
? ? ? ? return error(new BusinessException(e.getResultCode(),e.getMessage()));
? ? }
}
2、 前后端分離開(kāi)發(fā),日志應(yīng)該如何進(jìn)行記錄,在出現(xiàn)問(wèn)題的時(shí)候,方便定位問(wèn)題?
????使用logBack來(lái)進(jìn)行日志記錄,并把日志級(jí)別由info調(diào)制debug
3、 跨域的含義
????跨域,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制。所謂同源是指,域名,協(xié)議,端口均相同,有一個(gè)不同即為跨域。