您好,登錄后才能下訂單哦!
本篇內容主要講解“RestControllerAdvice無法捕獲filter中拋出的異常問題”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“RestControllerAdvice無法捕獲filter中拋出的異常問題”吧!
搭建springboot+shiro+jwt的時候,發現RestControllerAdvice全局異常處理無法獲取filter中的異常,然后找到這個老哥的文章,確實解決了我的問題:
記一次RestControllerAdvice無法攔截Filter內拋出異常
做個備忘也貼一下原文的內容
今天有同事用到Shiro使用JWT的時候在Filter里做身份驗證,然后在里面catch捕獲并拋出了自定義異常。我們這邊是用的RestControllerAdvice做統一異常處理,然后這個異常并沒有被RestControllerAdvice所攔截到
原因
請求進來 會按照 filter -> interceptor -> controllerAdvice -> aspect -> controller的順序調用當controller返回異常 也會按照controller -> aspect -> controllerAdvice -> interceptor -> filter來依次拋出
這種Filter發生的404、405、500錯誤都會到Spring默認的異常處理。如果你在配置文件配置了server.error.path的話,就會使用你配置的異常處理地址,如果沒有就會使用你配置的error.path路徑地址,如果還是沒有,默認使用/error來作為發生異常的處理地址。如果想要替換默認的非Controller異常處理直接實現Spring提供的ErrorController接口就行了
解決方案
新建一個ErrorControllerImpl 實現ErrorController 把ErrorPath 指向error 再寫一個方法把Error拋出 然后Controller全局統一異常處理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"); } } }最后,其實也是來自于:參考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 全局異常處理沒法處理過慮器中拋出的異常 * 和執行順序有關:filter -> interceptor -> controllerAdvice -> aspect -> controller * 當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) { // 設置一下信息,在application.properties中配置不生效,應該是和上面的構造方法傳的有關,先這么配置,待研究 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")) ? "系統錯誤" : body.get("message")); return new ResponseEntity<>(map, status); } }
同一個請求,使用第一種方式的截圖
使用第二種方式的截圖
個人感覺第一種方式更好
到此,相信大家對“RestControllerAdvice無法捕獲filter中拋出的異常問題”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。