Springboot專案錯誤碼的設計與實現
阿新 • • 發佈:2021-05-12
HTTP狀態碼和我們平時的錯誤碼不同,狀態碼太少了,無法滿足我們業務中的需求。
然而,所有請求都返回200,然後資料體裡包含錯誤碼的方式,又拋棄了HTTP狀態碼,拋棄了普遍公示。
所以推薦的做法:程式遇到錯誤時,前端返回錯誤碼和錯誤資訊。正常時,直接返回期望的結果。
一、返回格式
錯誤時,返回該選擇的HTTP狀態碼(500,403等等),body裡再包含errcode和errmsg詳細錯誤資訊。
{
"errcode":A2001,
"errmsg":"access_token expired"
}
正常時,返回200的HTTP狀態碼,body裡直接包含想要的資料。
{
"userid": "zhangsan",
"name": "張三",
"department": [1, 2],
"open_userid": "xxxxxx"
}
二、錯誤碼的設計
根據《阿里巴巴開發手冊》建議,錯誤碼的制定需
- 快速溯源,溝通標準化
- 不體現版本號和錯誤等級
- 全部正常時,返回00000
- 為字串型別,共5位(產生來源,四位數字編號)
- 不得與公司業務和組織架構掛鉤,應該自增數字
- 因為國際化i18n,不要用列舉定義錯誤碼
- 不能直接輸出給使用者作為提示資訊使用,不要替代錯誤資訊(errorMessage)
- 錯誤碼可分為一二三級巨集觀錯誤,跟HTTP狀態碼沒有關係
錯誤碼可以和國際化結合起來實現
在springboot專案的resources目錄中建立i18n資料夾,在資料夾下建立messages.properties等三個國際化配置檔案,IDEA會自動建立Resource Bundle並繫結這三個國際化配置檔案。
messages.properties和messages_zh_CN.properties檔案配置參考如下:
00000=請求成功 A0001=使用者端出錯 A0101=引數{0}缺少 A0201=引數{0}的型別不合法 A0301=引數{0}超過限制 A0401=引數{0}無效 A0501={0}已過期 A0601=結果{0}不存在 A0701=結果{0}已存在 A0801=刪除{0}禁止 A1001=使用者許可權不足 B0001=當前系統出錯 B0101=系統正忙,請稍後再試 C0001=第三方服務出錯
messages_en_US.properties檔案配置參考如下:
00000 = request successful
A0001 = client error
A0101 = missing parameter {0}
A0201 = illegal type of parameter {0}
A0301 = parameter {0} exceeds limit
A0401 = invalid parameter {0}
A0501 = {0} has expired
A0601 = result {0} does not exist
A0701= result {0} already exists
A0801 = delete {0} forbidden
A1001 = insufficient user rights
B0001 = current system error
B0101 = the system is busy, please try again later
C0001 = third party service error
其中,A代表使用者錯誤,B代表當前系統錯誤,C代表依賴的第三方服務錯誤,用0001表示第一類巨集觀錯誤。
錯誤碼可以自己設計,不斷自增,先到先得,以100為步長作為大類分類。
一般預設中文,然後設計好後,直接拿去翻譯,再貼上回來。
為了通用匹配錯誤,我用了{0}來匹配。如果想設定個性化資訊,可以接著往後配置A0102…等等提示資訊。
錯誤碼,也不用太多,要不然自己眼花繚亂,陷入麻煩裡了。最好做到,不查文件,就瞭解是什麼錯誤了。
三、工具類
需要自行將錯誤碼進行封裝,預設是中文
/**
* 錯誤碼相關方法
*/
public class ErrorCodeUtils {
/**
* 獲得錯誤碼對應的提示資訊
* @param errcode 錯誤碼
* @param params 匹配引數
* @return 返回錯誤提示資訊
*/
public static String getMessage(String errcode, String ...params){
ResourceBundle bundle = ResourceBundle.getBundle("i18n/messages", Locale.getDefault());
String msg = bundle.getString(errcode);
MessageFormat messageFormat = new MessageFormat(msg);
return messageFormat.format(params);
}
}
然後呼叫編寫的方法
@Test
public void testI18n() throws IOException {
System.out.println(ErrorCodeUtils.getMessage("A0101","ID"));
}
//輸出:引數ID缺少