您好,登錄后才能下訂單哦!
本篇內(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中拋出的異常問題”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(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)容。