SpringBoot 統一異常處理

一、什么是異常處理

異常(exception) 是程序運行過程中發(fā)生的事件, 該事件可以中斷程序指令的正常執(zhí)行流程.
1當Java程序運行時出現問題時,系統會自動檢測到該錯誤,并立即生成一個與該錯誤對應的異常對象
2:然后把該異常對象提交給JAVA虛擬機
3:JAVA虛擬機會自動尋找相應的處理代碼來處理這個異常,如果沒有找到,則程序終止
4:程序員可以自己編寫代碼來撲捉可能出現的異常,并編寫代碼來處理相應的異常.

二、實現方法

1、通過@ControllerAdvice@ExceptionHandler實現處理controller層的異常

@ControllerAdvice
@ResponseBody  //表示返回的對象,Spring會自動把該對象進行json轉化,最后寫入到Response中。
public class GlobalExceptionHandler {
?
    @ExceptionHandler(Exception.class) //表示讓Spring捕獲到所有拋出的SignException異常,并交由這個被注解的方法處理。
    @ResponseStatus(HttpStatus.BAD_REQUEST)  //表示設置狀態(tài)碼。
    String handleException(){
        return "Exception Deal!";
    }
}

這樣方法 handleException() 就會處理所有 Controller 層拋出的 Exception 及其子類的異常。
又因為service層的異常會拋出到controller層,所以service層拋出的異常也會被handleException處理.

2、異常是處理了,但是希望前端頁面能夠看到統一的返回結果,如下:

{
    "code": "33316",
    "msg": "This is NullPointerException.",
    "data": null
}

創(chuàng)建統一的JSON返回對象,code:消息類型,message:消息內容,url:請求的url,data:請求返回的數據
如創(chuàng)建類ResponseDto,無論正確的返回還是異常返回,都返回這個類對象

public class ResponseDto<T> {
    //錯誤碼
    private String code;
    //提示信息
    private String msg;
    //具體的內容
    private T data;
    public ResponseDto() {
    }
    public ResponseDto(String code, String msg) {
        this.code = code;
        this.msg = msg;
        this.data = null;
    }
    //getter和setter方法。。。
}

controller中,都返回這個對象,如下:

@RequestMapping(value = "/getUser")
    public ResponseDto getUser(String id){
        ResponseDto dto  = new ResponseDto();
        dto.setCode("10000");
        dto.setMsg("操作成功");
        dto.setData(userServiceImpl.getUser(id));
        return dto;
    }
?
    @RequestMapping(value = "/listUser")
    public ResponseDto getUser(){
        ResponseDto dto  = new ResponseDto();
        dto.setCode("10000");
        dto.setMsg("操作成功");
        dto.setData(userServiceImpl.listUser());
        return dto;
    }

看到有重復代碼,那就需要將重復代碼提取出來,寫一個工具類ResultUtil,在類中定義方法

 public static ResponseDto success(Object object){
        ResponseDto result = new ResponseDto();
        result.setCode("10000");
        result.setMsg("操作成功");
        result.setData(object);
        return result;
    }

這樣controller中的方法就可以改為:

    @RequestMapping(value = "/getUser")
    public ResponseDto getUser(String id){
        return ResultUtil.success(userServiceImpl.getUser(id));
    }
?
    @RequestMapping(value = "/listUser")
    public ResponseDto getUser(){
        return ResultUtil.success(userServiceImpl.listUser());
    }

異常處理的handleException方法也要做出對應的修改,這樣處理異常的返回才能是對應的格式

    @ExceptionHandler(Exception.class) //表示讓Spring捕獲到所有拋出的SignException異常,并交由這個被注解的方法處理。
    @ResponseBody  //表示返回的對象,Spring會自動把該對象進行json轉化,最后寫入到Response中。
    @ResponseStatus(HttpStatus.BAD_REQUEST)  //表示設置狀態(tài)碼。
    String handleException(){
        logger.error("Exception Deal!") ;
        return ResultUtil.error(CommonConstant.RESPONSE_CODE_UNKNOW_EXCEPTION,e.getMessage());
    }

三、對參數進行校驗。

 //添加全局異常處理流程,根據需要設置需要處理的異常,本文以MethodArgumentNotValidException為例
    @ExceptionHandler(value=MethodArgumentNotValidException.class)
    public Object MethodArgumentNotValidHandler(HttpServletRequest request,
                                                MethodArgumentNotValidException exception) {
        List<ObjectError> errors =exception.getBindingResult().getAllErrors();
        StringBuffer errorMsg=new StringBuffer();
        errors.stream().forEach(x -> errorMsg.append(x.getDefaultMessage()).append(";"));
        logger.error("---MethodArgumentNotValidException Handler--- ERROR: {}", errorMsg.toString());
        respBean.setRespCode(RespCodeConstant.VALIDATE_ERROR);
        respBean.setRespDesc(RespCodeConstant.VALIDATE_ERROR_DESC);
        respBean.setRespData(errorMsg.toString());
        return respBean;
    }

在contorller中的方法中添加@Validated校驗

public RespBean getWeeklyVisitTrend(@RequestBody @Validated ParamsDto dto) {

在ParamsDto 里面的字段添加上具體的校驗,以及出錯時打印的信息

@NotBlank(message = "params.dto.begin.date.null")
    private String begin_date;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容