SpringBoot自定義異常,優雅解決業務邏輯中的錯誤


概要

你是不是在為業務邏輯中出現的異常弄的焦頭爛額,常常在后台報錯,前端卻無法提示錯誤內容,導致用戶體驗極差?比如下單失敗,前端只能提示下單失敗,但是卻不知道為什么失敗,是庫存不足,還是余額不足,亦或是商品已經失效?

之前想在 service 層直接返回封裝好的 Reponse(code, data,msg) 對象,這樣的話我就直接在service層提示出錯原因了(msg:錯誤提示),但是這樣代碼就不夠美觀,因為Response原本是設計為后端統一返回的對象,太臃腫,最后決定用自定義異常來完成。

定義常見的錯誤枚舉類


import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * @author: zp
 * @Date: 2019-10-10 14:47
 * @Description:
 */
@Getter
@AllArgsConstructor
public enum  ErrorType {
    /**
     * 錯誤類型
     */
    OBJECT_NOT_FOUND(0,"對象不存在"),

    INVALID_PARAMS(1,"參數不正確"),

    result_not_exist(2,"記錄不存在")

    ;

    /**
     * 錯誤碼
     */
    private int code;

    /**
     * 提示信息
     */
    private String msg;
}

自定義異常

提供了兩個構造方法,一個用來提示常見的錯誤(枚舉類中的),另一個提示不常用的(一次兩次的那種),可拓展。

import com.example.demojpa.enums.ErrorType;
import lombok.Getter;

/**
 * @author: zp
 * @Date: 2019-10-10 14:42
 * @Description:
 */
@Getter
public class ServiceException extends RuntimeException{
    private Integer code;

    /**
     * 使用已有的錯誤類型
     * @param type 枚舉類中的錯誤類型
     */
    public ServiceException(ErrorType type){
        super(type.getMsg());
        this.code = type.getCode();
    }

    /**
     * 自定義錯誤類型
     * @param code 自定義的錯誤碼
     * @param msg 自定義的錯誤提示
     */
    public ServiceException(Integer code, String msg){
        super(msg);
        this.code = code;
    }
}

定義響應對象及工具類(這個不是必需的)

  • 響應對象

    /**
     * @author: zp
     * @Date: 2019-10-10 15:22
     * @Description:
     */
    @Data
    public class Response<T> {
    
    		/**
    		 * 狀態碼
    		 */
    		private Integer code;
    
    		/**
    		 * 請求成功時返回的對象
    		 */
    		private T data;
    
    		/**
    		 * 提示信息
    		 */
    		private String msg;
    
    }
    
  • 工具類

    import com.example.demojpa.model.Response;
    
    /**
     * @author: zp
     * @Date: 2019-10-10 15:48
     * @Description:
     */
    public class ResponseUtils {
    		/**
    		 * 調用成功
    		 */
    		private static final String SUCCESS = "調用成功!";
    
    		public static Response success(Object obj){
    				Response res = new Response();
    				res.setCode(200);
    				res.setData(obj);
    				res.setMsg(SUCCESS);
    				return res;
    		}
    
    		public static Response success(){
    				return success(null);
    		}
    
    		public static Response error(Integer code, String msg){
    				Response res = new Response();
    				res.setCode(code);
    				res.setMsg(msg);
    				return res;
    		}
    
    }
    

異常處理類

import com.example.demojpa.exception.ServiceException;
import com.example.demojpa.model.Response;
import com.example.demojpa.utils.ResponseUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author: zp
 * @Date: 2019-10-10 15:11
 * @Description:
 */

@ControllerAdvice 
public class ServiceExceptionHandler {

    /**
     * @ExceptionHandler相當於controller的@RequestMapping
     * 如果拋出的的是ServiceException,則調用該方法
     * @param se 業務異常
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Response handle(ServiceException se){
        return ResponseUtils.error(se.getCode(),se.getMessage());
    }
}

測試

為了簡單一點,我直接在controller中拋異常,看看結果。

@GetMapping("/exception/{msg}")
    public String exception(@PathVariable String msg) throws InvalidParamExceptionAbstract, NoSuchObjectExceptionAbstract {
        if(StringUtils.isEmpty(msg)){
            throw new ServiceException(ErrorType.INVALID_PARAMS);
        }else if("null".equals(msg)) {
            throw new ServiceException(ErrorType.OBJECT_NOT_FOUND);
        }else{
            throw new ServiceException(250,"瞧你那傻樣!");
        }
    }

file

file

關注我不會讓你失望喲~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM