springMVC 統一異常處理 返回JSON數據

需求

在後臺開發中,難免會存在一些異常,如果我們在controller中一個一個的去try catch處理,會很繁瑣,並且不好維護;如果在web.xml配置錯誤頁面,會導致返回一個試圖給前臺,對於前後端分離的不太友好,前臺無法解析,這明顯不是我們想要的,我們需要的是返回串JSON的錯誤碼給前臺;

@ControllerAdvice

從spring3.2開始,增加了新註解@ControllerAdvice,控制器增強的註解。其原理是使用AOP對Controller控制器進行增強(前置增強、後置增強、環繞增強,AOP原理請自行查閱);這樣我們就可以自行對控制器的方法進行調用前(前置增強)和調用後(後置增強)的處理。

如果要返回JSON格式,只需要創建一個ExceptionHandler的class 用@ControllerAdvice註解,裏面通過@ExceptionHandler來註解了的方法處理數據,處理中將Exception轉換爲Json格式返回即可。

代碼

package com.XXX.XXX

import com.XXXX.common.GenericResponse;
import com.XXXX.common.ServiceError;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;


/**
 * 招生統一異常處理
 */
@ControllerAdvice
public class XXXXExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(XXXXExceptionHandler.class);

    /**
     * 運行時異常
     * @param runtimeException
     * @return 
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public GenericResponse runtimeExceptionHandler(RuntimeException runtimeException) {
        logger.error(runtimeException.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"系統運行異常");
    }

    /**
     * 空指針異常
     * @param ex
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public GenericResponse nullPointerExceptionHandler(NullPointerException ex) {
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"系統空指針異常");
    }


    /*----- REQUEST ERROR -----*/

    //400錯誤
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public GenericResponse requestNotReadable(HttpMessageNotReadableException ex){
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"參數格式錯誤(缺少分隔符或結束標籤)");
    }

    //400錯誤
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public GenericResponse requestTypeMismatch(TypeMismatchException ex){
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"參數類型不匹配");
    }

    //400錯誤
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public GenericResponse requestMissingServletRequest(MissingServletRequestParameterException ex){
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"缺少請求參數");
    }

    //405錯誤
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public GenericResponse request405(){
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"不支持該請求方式");
    }

}

說明

  1. 需要注意的是該類一定要存放到能夠被spring掃描到的地方
  2. 其中GenericResponse 及 ServiceError是自定義的響應結果,可修改爲自己定義的(因爲各自的項目的響應結果都不一樣,這邊就不貼出來了)
  3. @ExceptionHandler表示需要處理的異常類型
  4. @ResponseStatus表示修改返回的http狀態
  5. @ResponseBody表示返回JSON、因爲GenericResponse爲一個實體對象,所以最終將對象轉爲JSON再返回給前臺

效果圖

後臺controller拋出異常,無需try catch
500異常預覽

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