github源碼:controller-handler-master
在開發(fā)項目中慎玖,對于controller返回數(shù)據(jù)同時返回可能大家都能夠做到隘道。也就是定義一個相應(yīng)類澡罚,里面有code
, msg
,content(或data)
碍沐。
在此基礎(chǔ)上可能還會再封裝以下身隐,搞個基礎(chǔ)controller類,有success,fail等方法可以調(diào)用锤灿。
但是對于異常信息返回第股,可能稍微有點麻煩。
首先吼拥,是code確定倚聚,報錯時可能直接在try-catch中返回一個錯誤狀態(tài)碼500,或是403等等非200的狀態(tài)碼凿可。但是由于不是使用變量管理惑折,也就意味著不同方法不同異常的狀態(tài)碼可能相同授账,或是相同異常,返回的狀態(tài)碼不同惨驶。
第二白热,msg確定。不同方法catch到錯誤粗卜,返回code可能相同屋确,但是msg可能就是當(dāng)前異常的相關(guān)信息,甚至直接寫成e.getMessage()
续扔。特別是e.getMessage()
可能會暴露不必要的信息攻臀,甚至是數(shù)據(jù)庫信息。
那么怎么才能保證code跟msg一對一對應(yīng)起來呢纱昧?
此時枚舉都起到了關(guān)鍵作用刨啸。可能有的人想到靜態(tài)變量和map砌些,也可以但是沒有枚舉類更直觀呜投。
這個枚舉類可以參考Spring-Framework的HttpStatus
自定義項目相關(guān)枚舉類:
public enum ReturnTEnum {
SUCCESS(200, "SUCCESS"),
ERROR(500, "服務(wù)異常"),
UNKNOWN_ERROR(5000, "未知錯誤"),
PARAMETER_EMPTY(210,"參數(shù)為空"),
PARAMETER_INVALID(211,"參數(shù)錯誤"),
ARITHMETIC_ERROR(212,"計算錯誤"),
DATE_ERROR_FORMAT_ERROR(212,"日期格式錯誤"),
DATE_ERROR_START_LARGE_END(213,"開始時間大于結(jié)束時間"),
FORBIDDEN(403, "拒絕訪問"),
// todo: 更多自定義返回錯誤信息,均在此重新定義
;
private int code;
private String msg;
// ....省略構(gòu)造存璃,get方法
}
枚舉類建好了仑荐,怎么在處理異常時獲取相應(yīng)的枚舉類值呢?
可以自定義異常類SkyException
纵东,里面有code粘招,msg。
整體思路具體參考如下:
Controller響應(yīng)數(shù)據(jù)統(tǒng)一管理
1. 返回數(shù)據(jù)統(tǒng)一:
所有controller都繼承BaseController
類
- 返回正常數(shù)據(jù):
return success("hello world");
- 返回錯誤數(shù)據(jù):
return error(ReturnTEnum.ARITHMETIC_ERROR, e);
或throw new SkyException(ReturnTEnum.ARITHMETIC_ERROR, e);
即可
{
"code": 200,
"msg": "SUCCESS",
"content": "sdf"
}
或
{
"code": 500,
"msg": "服務(wù)器內(nèi)部異常",
"content": "/test/err"
}
其中
字段 | 類型 | 說明 |
---|---|---|
code | int | 狀態(tài)碼 |
msg | String | 狀態(tài)信息 |
content | 泛型T偎球。允許序列化類 | 業(yè)務(wù)數(shù)據(jù) |
2. 全局異常處理
- 使用
@ControllerAdvice
和@ExceptionHandler
注解處理全局異常 - 參考
cn.skyjilygao.springboot.core.interceptor.GlobalExceptionHandler
類
為了能夠更好統(tǒng)一返回狀態(tài)信息洒扎,捕獲異常需要同時狀態(tài)碼和狀態(tài)信息,怎么辦衰絮?使用自定義異常類SkyException
-1. 增加了枚舉類cn.skyjilygao.springboot.controller.ReturnTEnum
也可以使用HttpStatus
.
-2. 異常類SkyException
/**
* 自定義異常處理類袍冷。用于接口返回時可以指定異常枚舉類。便于返回狀態(tài)碼管理
* @author skyjilygao
* @since 1.8
*/
public class SkyException extends SkyExceptionBase {
public SkyException(ReturnTEnum httpStatus) {
super(httpStatus.getCode(), httpStatus.getMsg());
}
public SkyException(ReturnTEnum httpStatus, Exception e) {
super(httpStatus.getCode(), httpStatus.getMsg(), e);
}
public SkyException(HttpStatus httpStatus) {
super(httpStatus);
}
public SkyException(HttpStatus httpStatus, Exception e) {
super(httpStatus, e);
}
}
-3. 對于可控異常猫牡,可以拋出SkyException
同時指定相應(yīng)枚舉類即可
例如:對于計算胡诗,可能拋出被除數(shù)不能為0,則可以捕獲以下淌友。枚舉類就是ReturnTEnum.ARITHMETIC_ERROR
public ReturnT err(){
try {
int a = 2;
int b = 0;
return success(a/b);
}catch (Exception e){
// return error(ReturnTEnum.ARITHMETIC_ERROR, e);
throw new SkyException(ReturnTEnum.ARITHMETIC_ERROR, e);
}
}
-4. 對于不可控異常煌恢,可以在全局異常處理類中指定默認(rèn)狀態(tài)碼。
@ResponseBody
@ExceptionHandler(value = {Exception.class})
public ReturnT defaulExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception {
String uri = getUri(request);
log.error("handler Exception: request uri={}. with error message={}", uri, e.getMessage(), e);
return new ReturnT(ReturnTEnum.ERROR.getCode(), "服務(wù)器內(nèi)部異常", uri);
}
3. 記錄調(diào)用者IP以及請求參數(shù)信息
利用攔截器記錄IP和請求相關(guān)數(shù)據(jù)震庭。這樣跟其他配合時瑰抵,就能清楚看到參數(shù)等數(shù)據(jù)不至于相互扯皮
4. 日志記錄
使用logback
記錄,保留最近3天的日志
如何移至到自己的項目中
- 將
cn.skyjilygao.springboot.core
下所有文件復(fù)制到自己項目公共模塊或第三方庫中器联,重新編譯安裝 - 將
ReturnTEnum
,BaseController
,SkyException
復(fù)制到項目的公共文件夾中二汛。然后在ReturnTEnum
增加自定義枚舉即可
如何使用
- 使用本項目測試時婿崭,只需在
ReturnTEnum
增加自定義枚舉即可