前後端分離項目 — Java後臺統一錯誤消息處理

1、前言

一般我們後臺出錯報Exception都是直接拋出來的,但是微信公衆號,或者支付寶支付等等,他們的異常都有錯誤碼對應錯誤信息,他們是如何根據錯誤信息展示對應的錯誤碼提供給前端的呢,這也就是我們要說的統一錯誤消息處理機制。

clipboard.png

clipboard.png

2、Java實現

首先創建一個Result類,這個類作用是設置消息碼以及消息文本還有消息數據,如下所示

package com.xfind.util.result;

public class Result<T> {
    private int code;
    private String message;
    private T data;

    public Result(){

    }

    public Result(int code, String message, T data) {
        this(code, message);
        this.data = data;
    }

    public Result(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

設置之後 ,我們接下來再創建一個ResultCode類,這個類的作用是具體的消息碼和消息,如下所示:

package com.xfind.util.result;

/**
 * 異常處理狀態碼
 */
public enum ResultCode {

    SUCCESS(0, "請求成功"),
    Unknown_Exception(-1, "未知異常"),

    USER_NOT_FOUND(10001, "沒有找到此用戶"),
    USERNAME_NOT_BLANK(10002, "用戶名不能爲空"),
    USERNAME_EXIST(10003, "用戶名已經存在"),
    USERTYPE_ERROR(100031, "用戶類型不正確"),
    PHONE_WROND(10004, "手機號不正確"),
    SMS_CODE_ERROR(10007, "手機驗證碼不正確"),
    PHONE_EXIST(10008, "手機號已經存在"),
    USER_EMPTY_EXCEPTION(10009, "用戶名、手機號或者郵箱爲空"),
    USER_TOKEN_EXCEPTION(10010, "從TOKEN中未查到相關用戶信息"),
    USERNAME_PASSWORD_EXCEPTION(10011, "用戶名或者密碼錯誤"),

    EMAIL_SERVER_ECCEPTION(10012, "阿里雲郵件服務端出錯"),
    EMAIL_CLIENT_ECCEPTION(10013, "阿里雲郵件客戶端出錯"),
    EMAIL_SEND_ECCEPTION(10014, "阿里雲郵件發送出錯"),
    EMAIL_WROND(10015, "郵箱不正確"),
    EMAIL_CODE_WROND(10016, "郵箱驗證碼不正確"),
    EMAIL_EXIST(10017, "郵箱已經存在"),

    LOGIN_METHOD_WROND(10018, "登錄方式不正確"),
    CODE_EMPTY(10019, "驗證碼不爲空"),
    PASSWORD_EMPTY(10020, "密碼不爲空"),
    TOKEN_EXCEPTION(10021, "TOKEN認證出錯"),

    USER_AUTH_FAILD(10022, "用戶認證失敗"),

    USER_ACCESS_DENIED(10023, "用戶無權限登錄"),

    CODE_SEND_FAILD(10030, "驗證碼發送失敗"),

    ACTION_MONGODB_ERROR(10100, "操作MONGODB數據庫出錯"),
    OPERATION_TOO_FREQUENT(10101, "請求過於頻繁,請稍候再試"),

    GOLD_COINS_INSUFFICIENT(10025,"金幣餘額不足"),
    CODE_EXIST(10023,"編號已存在"),
    TESTCODE_EXIST(10033,"答題碼已存在"),
    TESTCODE_NOEXIST(10034,"答題碼不存在"),
    TESTCODE_ERROR(10036,"提交數已達上限"),
    TESTCENTER_NOEXIST(10035,"測試題不存在"),
    NAME_EXIST(10024,"名稱已存在"),
    NOT_EXIST_EMAIL(10025,"該企業用戶沒有分配郵箱"),
    MAIL_REACH_MAX(10026,"達到收取郵箱上限"),
    MAIL_NEW_NOTEXIST(10027,"郵箱中沒有可導入的簡歷"),
    PWD_CONFIRM_ERROR(10029,"兩次密碼不一致"),
    PWD_ERROR(10030,"密碼不正確"),
    ENTER_OR_TALENT_NOT_EXITS(10028,"企業或人才庫簡歷不存在"),
    PHONE_EMPTY(10031, "手機號不能爲空"),
    EMAIL_EMPTY(10032, "郵箱不能爲空"),
    NO_USABLE_MAIL(10040,"沒有可用郵箱"),

    REQUESTRECORD_EXIST(10050,"簡歷已投遞"),
    TALENTRESERVER_EXIST(10051,"簡歷已存在於人才儲備庫中,請勿重複添加"),

    DEVICE_ID_EMPTY(10052,"設備ID:deviceId不能爲空"),
    DELETE_CONNECT_ERROR(10053,"刪除connect出錯");

    private int code;
    private String message;

    ResultCode(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

好了,有了Result和ResultCode類,我們就可以來編寫異常並返回給前端了,不過在這之前我們還要創建兩個類:DomainException和SuccessResult,

package com.xfind.exception;

import com.xfind.util.result.ResultCode;

public class DomainException extends RuntimeException {
    private int errCode = ResultCode.Unknown_Exception.getCode();

    public DomainException() {
        super(ResultCode.Unknown_Exception.getMessage());
    }

    public DomainException(ResultCode resultCode) {
        super(resultCode.getMessage());
        this.errCode = resultCode.getCode();
    }

    public int getErrCode() {
        return errCode;
    }

    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }
}

DomainException的作用是要拋出的異常類,從代碼中可以看出它是繼承RuntimeException類的,所以可以使用throw new DomainException(ResultCode.XX);這樣就可以拋到前端。

package com.xfind.util.result;


public class SuccessResult<T> extends Result<T> {
    public SuccessResult(){

    }

    public SuccessResult(T data) {
        super(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
    }
}

這個類的作用是輔助類,把Code和Message都封裝到這個類,就可以直接返回到前端了。

3、設置統一異常處理

我們再添加一個GlobalExceptionHandler類,來處理每個拋出DomainException類返回的數據,前返回Result給前端了,如下所示:

/**
 * 統一異常處理
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = DomainException.class)
    public Result domainExceptionHandler(HttpServletRequest req,
                                         DomainException e) throws Exception {
        e.printStackTrace();
        Result result = new Result(e.getErrCode(), e.getMessage());
        return result;
    }
}

4、測試

現在我們編寫一個類來測試我們剛剛寫的類的運行情況,如下所示

@GetMapping("/isRegister")
    public ResponseEntity isRegister(@RequestParam String user) {
        boolean has_phone = smsService.isExist(user);
        if (has_phone) {
            throw new DomainException(ResultCode.PHONE_EXIST);
        }

        boolean has_email = emailService.isExist(user);
        if (has_email) {
            throw new DomainException(ResultCode.EMAIL_EXIST);
        }
        String str = "該手機號或者郵箱沒有被註冊,可以註冊本系統";
        Result result = new SuccessResult<>(str);
        return ResponseEntity.ok(result);
    }

該方法是判斷用戶是否已經被註冊,方法裏面先判斷是否有相同手機或者郵箱,如果有就招聘異常給前端,否則則返回正確信息給前端,我們使用POSTMan來測試下
1)首先我們輸入一個已經存在的手機號

clipboard.png

clipboard.png

2)我們再輸入一個已經存在的郵箱

clipboard.png

clipboard.png

3)我們再輸入一個不存在存在的手機

clipboard.png

5、總結

1、首先建立一個錯誤碼和錯誤消息類,然後再把消息返回,返回的時候要設置成JSON拋給前端
2、我這裏的消息碼使用的是int,你也可以設置成String,這個看你需求了

如果你覺得幫助到你了,可以請我喝一杯咖啡^_^

clipboard.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章