springmvc、 springboot 項目全局異常處理

異常在項目中那是不可避免的,通常情況下,我們需要對全局異常進行處理,下面介紹兩種比較常用的情況。

準備工作:

在捕獲到異常的時候,我們通常需要返回給前端錯誤碼,錯誤信息等,所以我們需要手動封裝一個jsonData對象,這裏爲了方便,我直接通過返回布爾類型來進行判斷成功或失敗,在實際的項目中更多是返回狀態碼 比如 0、1 、404 、500 等,在這裏不影響我們演示。

jsondata對象

自定義一個異常  (注意需要繼承RuntimeException,因爲在spring中僅有RuntimeException支持事務)

 

情況一、對全局進行捕獲,並統一返回json數據

我們通過@ControllerAdvice的方式來捕獲全局異常

主要代碼如下:

import com.me.exception.RbacException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
@Slf4j
public class ExceptionHandReturnJson {

    private final String UNKNOW_EX_MSG = "未知錯誤";

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public JsonData handle(Exception e){
        JsonData result = new JsonData();
        /*判斷異常的類型*/

        // 如果是自定義異常
        if(e instanceof RbacException){
            log.error("【自定義異常】:{}"+e.getMessage());
            result = JsonData.fail(e.getMessage());
        }else{
            log.error("【系統異常】:{}"+e.getMessage());
             result = JsonData.fail(UNKNOW_EX_MSG);
        }
        return result;
    }
}

  然後確保我們這個類所在的包被掃描到即可。

  下面我們自定義一個類,並手動產生一個異常:

運行結果:

 

情況二、對全局異常進行捕獲,返回modelandview類型

我們通過實現HandlerExceptionResolver 的方式來捕獲全局異常

主要代碼如下:

package com.me.common;

import com.me.exception.RbacException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 全局異常處理
 */

@Slf4j
public class ExceptionHand implements HandlerExceptionResolver {


    private final String UNKNOW_EX_MSG = "未知錯誤";

    /**
     * 通過實現HandlerExceptionResolver 接口,對捕獲到的異常進行處理
     * 當然,我們需要在spring容器中創建這個bean
     * @param request
     * @param response
     * @param o
     * @param e
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object o, Exception e) {
        // 請求地址
//        String url = request.getRequestURL().toString();

        ModelAndView mav = new ModelAndView();
        // 如果是自定義異常
        if(e instanceof RbacException){
            log.error("【自定義異常】:{}"+e.getMessage());
            JsonData result = JsonData.fail(e.getMessage());
            mav.addObject("result",result);
        }else{
            log.error("【系統異常】:{}"+e.getMessage());
            JsonData result = JsonData.fail(UNKNOW_EX_MSG);
            mav.addObject("result",result);
        }
        // 設置異常處理返回的頁面,在/views/exception.jsp
        mav.setViewName("exception");
        return mav;
    }

}

然後我們需要在spring容器中創建這個類的bean , 按照springmvc和springboot不同的做法都可以。

 

  同樣,我們還是用剛纔的方法進行測試

因爲返回的是modelAndView類型的對象,所以我們需要創建一個view

運行結果:

 

===========================================================================================

總結:

上面就是兩種種捕獲全局異常進行處理的不同方式,

1.實現HandlerExceptionResolver接口,返回modelAndView類型

2.通過@ControllerAdvice註解捕獲,並通過@ResponseBody返回json類型

具體使用哪種看實際的項目,個人更喜歡第一種,統一返回json類型。

其他:

更規範的json返回對象是code碼而不是boolean類型的,這裏只爲了做演示。那麼在我們使用code碼的時候,我們拋異常的時候可以自定義傳入code以及msg ,這時建議用枚舉來管理二者關係,拋異常的時候傳入枚舉類型,捕獲的時候再從枚舉中取值。

更詳細的課程教學,請看廖師兄的課程  https://www.imooc.com/learn/810

 

 

 

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