中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Spring Boot統一異常處理能攔截所有的異常嗎

發布時間:2021-07-02 16:00:03 來源:億速云 閱讀:278 作者:chen 欄目:開發技術

本篇內容介紹了“Spring Boot統一異常處理能攔截所有的異常嗎”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

通常我們在Spring  Boot中設置的統一異常處理只能處理Controller拋出的異常。有些請求還沒到Controller就出異常了,而這些異常不能被統一異常捕獲,例如Servlet容器的某些異常。今天我在項目開發中就遇到了一個,這讓我很不爽,因為它返回的錯誤信息格式不能統一處理,我決定找個方案解決這個問題。

ErrorPageFilter

Spring Boot統一異常處理能攔截所有的異常嗎

Whitelabel Error Page

這類圖相信大家沒少見,Spring Boot 只要出錯,體現在頁面上的就是這個。如果你用Postman之類的測試出了異常則是:

{   "timestamp": "2021-04-29T22:45:33.231+0000",   "status": 500,   "message": "Internal Server Error",   "path": "foo/bar" }

這個是怎么實現的呢?Spring  Boot在啟動時會注冊一個ErrorPageFilter,當Servlet發生異常時,該過濾器就會攔截處理,將異常根據不同的策略進行處理:當異常已經在處理的話直接處理,否則轉發給對應的錯誤頁面。有興趣的可以去看下源碼,邏輯不復雜,這里就不貼了。

另外當一個 Servlet 拋出一個異常時,處理異常的Servlet可以從HttpServletRequest里面得到幾個屬性,如下:

Spring Boot統一異常處理能攔截所有的異常嗎

異常屬性

我們可以從上面的幾個屬性中獲取異常的詳細信息。

默認錯誤頁面

通常Spring Boot出現異常默認會跳轉到/error進行處理,而/error的相關邏輯則是由BasicErrorController實現的。

@Controller @RequestMapping("${server.error.path:${error.path:/error}}") public class BasicErrorController extends AbstractErrorController {     //返回錯誤頁面   @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)  public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {   HttpStatus status = getStatus(request);   Map<String, Object> model = Collections     .unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));   response.setStatus(status.value());   ModelAndView modelAndView = resolveErrorView(request, response, status, model);   return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);  }     // 返回json  @RequestMapping  public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {   HttpStatus status = getStatus(request);   if (status == HttpStatus.NO_CONTENT) {    return new ResponseEntity<>(status);   }   Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));   return new ResponseEntity<>(body, status);  }   // 其它省略 }

而對應的配置:

@Bean @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT) public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,       ObjectProvider<ErrorViewResolver> errorViewResolvers) {    return new BasicErrorController(errorAttributes, this.serverProperties.getError(),          errorViewResolvers.orderedStream().collect(Collectors.toList())); }

所以我們只需要重新實現一個ErrorController并注入Spring  IoC就可以替代默認的處理機制。而且我們可以很清晰的發現這個BasicErrorController不但是ErrorController的實現而且是一個控制器,如果我們讓控制器的方法拋異常,肯定可以被自定義的統一異常處理。所以我對BasicErrorController進行了改造:

@Controller @RequestMapping("${server.error.path:${error.path:/error}}") public class ExceptionController extends AbstractErrorController {       public ExceptionController(ErrorAttributes errorAttributes) {         super(errorAttributes);     }       @Override     @Deprecated     public String getErrorPath() {         return null;     }      @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)     public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {         throw new RuntimeException(getErrorMessage(request));     }      @RequestMapping     public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {         throw new RuntimeException(getErrorMessage(request));     }      private String getErrorMessage(HttpServletRequest request) {         Object code = request.getAttribute("javax.servlet.error.status_code");         Object exceptionType = request.getAttribute("javax.servlet.error.exception_type");         Object message = request.getAttribute("javax.servlet.error.message");         Object path = request.getAttribute("javax.servlet.error.request_uri");         Object exception = request.getAttribute("javax.servlet.error.exception");          return String.format("code: %s,exceptionType: %s,message: %s,path: %s,exception: %s",                 code, exceptionType, message, path, exception);     } }

直接拋異常,簡單省力!凡是這里捕捉的到的異常大部分還沒有經過Controller,我們通過ExceptionController中繼也讓這些異常被統一處理,保證整個應用的異常處理對外保持一個統一的門面。

“Spring Boot統一異常處理能攔截所有的異常嗎”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

重庆市| 汉阴县| 贵定县| 泰兴市| 广州市| 黑龙江省| 江口县| 遂宁市| 木兰县| 于都县| 临沭县| 新沂市| 疏勒县| 祁阳县| 五河县| 拉孜县| 奉化市| 汤阴县| 鹤岗市| 阿鲁科尔沁旗| 花莲县| 稻城县| 华阴市| 河东区| 九龙县| 合水县| 海原县| 大埔区| 温州市| 平泉县| 漳浦县| 乐平市| 治县。| 和平县| 自贡市| 江北区| 安吉县| 朝阳市| 当雄县| 沙洋县| 大名县|