溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

RestControllerAdvice無法捕獲filter中拋出的異常問題

發(fā)布時間:2021-07-07 16:55:55 來源:億速云 閱讀:2347 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“RestControllerAdvice無法捕獲filter中拋出的異常問題”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“RestControllerAdvice無法捕獲filter中拋出的異常問題”吧!

搭建springboot+shiro+jwt的時候,發(fā)現(xiàn)RestControllerAdvice全局異常處理無法獲取filter中的異常,然后找到這個老哥的文章,確實(shí)解決了我的問題:

記一次RestControllerAdvice無法攔截Filter內(nèi)拋出異常

做個備忘也貼一下原文的內(nèi)容

今天有同事用到Shiro使用JWT的時候在Filter里做身份驗(yàn)證,然后在里面catch捕獲并拋出了自定義異常。我們這邊是用的RestControllerAdvice做統(tǒng)一異常處理,然后這個異常并沒有被RestControllerAdvice所攔截到

原因
請求進(jìn)來 會按照 filter -> interceptor -> controllerAdvice -> aspect -> controller的順序調(diào)用

當(dāng)controller返回異常 也會按照controller -> aspect -> controllerAdvice -> interceptor -> filter來依次拋出

這種Filter發(fā)生的404、405、500錯誤都會到Spring默認(rèn)的異常處理。如果你在配置文件配置了server.error.path的話,就會使用你配置的異常處理地址,如果沒有就會使用你配置的error.path路徑地址,如果還是沒有,默認(rèn)使用/error來作為發(fā)生異常的處理地址。如果想要替換默認(rèn)的非Controller異常處理直接實(shí)現(xiàn)Spring提供的ErrorController接口就行了

解決方案
新建一個ErrorControllerImpl 實(shí)現(xiàn)ErrorController 把ErrorPath 指向error 再寫一個方法把Error拋出 然后Controller全局統(tǒng)一異常處理RestControllerAdvice就能捕獲到異常了

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Joe
 * createTime 2020/07/27 14:39
 * mail joe-code@foxmail.com
 */
@Controller
public class ErrorControllerImpl implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping("/error")
  	
    public void handleError(HttpServletRequest request) throws Throwable {
        if (request.getAttribute("javax.servlet.error.exception") != null) {
            throw (Throwable) request.getAttribute("javax.servlet.error.exception");
        }
    }
}

最后,其實(shí)也是來自于:參考stackoverflow鏈接 https://stackoverflow.com/questions/34595605/how-to-manage-exceptions-thrown-in-filters-in-spring

 第二種方式也能解決,也記錄一下:

package com.hs.demo.exception;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * GlobalException 全局異常處理沒法處理過慮器中拋出的異常
 * 和執(zhí)行順序有關(guān):filter -> interceptor -> controllerAdvice -> aspect -> controller
 * 當(dāng)controller返回異常 也會按照controller -> aspect -> controllerAdvice -> interceptor -> filter來依次拋出
 * 注:使用ErrorControllerImpl來解決了,這個先注掉
 */
//@RestController
public class MyErrorController extends BasicErrorController {

    public MyErrorController() {
        super(new DefaultErrorAttributes(), new ErrorProperties());
    }

    @Override
    @RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        // 設(shè)置一下信息,在application.properties中配置不生效,應(yīng)該是和上面的構(gòu)造方法傳的有關(guān),先這么配置,待研究
        getErrorProperties().setIncludeException(true);
        getErrorProperties().setIncludeMessage(ErrorProperties.IncludeAttribute.ALWAYS);
        getErrorProperties().setIncludeStacktrace(ErrorProperties.IncludeStacktrace.ALWAYS);
        Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        HttpStatus status = getStatus(request);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", body.get("status"));
        map.put("message", "".equals(body.get("message")) ? "系統(tǒng)錯誤" : body.get("message"));
        return new ResponseEntity<>(map, status);
    }
}

同一個請求,使用第一種方式的截圖

RestControllerAdvice無法捕獲filter中拋出的異常問題

使用第二種方式的截圖

RestControllerAdvice無法捕獲filter中拋出的異常問題

個人感覺第一種方式更好

到此,相信大家對“RestControllerAdvice無法捕獲filter中拋出的異常問題”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI