1. 程式人生 > 其它 >Springboot專案錯誤碼的設計與實現

Springboot專案錯誤碼的設計與實現

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缺少