您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Springboot項目中如何實現異常處理自定義,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
背景
Springboot 默認把異常的處理集中到一個ModelAndView中了,但項目的實際過程中,這樣做,并不能滿足我們的要求。具體的自定義異常的處理,參看以下
具體實現
如果仔細看完spring boot的異常處理詳解,并且研究過源碼后,我覺得具體的實現可以不用看了。。。
重寫定義錯誤頁面的url,默認只有一個/error
@Bean public EmbeddedServletContainerCustomizer containerCustomizer(){ return new EmbeddedServletContainerCustomizer(){ @Override public void customize(ConfigurableEmbeddedServletContainer container) { container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404")); container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500")); container.addErrorPages(new ErrorPage(java.lang.Throwable.class,"/error/500")); } }; }
重寫通過實現ErrorController,重寫BasicErrorController的功能實現
/** * 重寫BasicErrorController,主要負責系統的異常頁面的處理以及錯誤信息的顯示 * @see org.springframework.boot.autoconfigure.web.BasicErrorController * @see org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration * * @author Jonathan * @version 2016/5/31 11:22 * @since JDK 7.0+ */ @Controller @RequestMapping(value = "error") @EnableConfigurationProperties({ServerProperties.class}) public class ExceptionController implements ErrorController { private ErrorAttributes errorAttributes; @Autowired private ServerProperties serverProperties; /** * 初始化ExceptionController * @param errorAttributes */ @Autowired public ExceptionController(ErrorAttributes errorAttributes) { Assert.notNull(errorAttributes, "ErrorAttributes must not be null"); this.errorAttributes = errorAttributes; } /** * 定義404的ModelAndView * @param request * @param response * @return */ @RequestMapping(produces = "text/html",value = "404") public ModelAndView errorHtml404(HttpServletRequest request, HttpServletResponse response) { response.setStatus(getStatus(request).value()); Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); return new ModelAndView("error/404", model); } /** * 定義404的JSON數據 * @param request * @return */ @RequestMapping(value = "404") @ResponseBody public ResponseEntity<Map<String, Object>> error404(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); HttpStatus status = getStatus(request); return new ResponseEntity<Map<String, Object>>(body, status); } /** * 定義500的ModelAndView * @param request * @param response * @return */ @RequestMapping(produces = "text/html",value = "500") public ModelAndView errorHtml500(HttpServletRequest request, HttpServletResponse response) { response.setStatus(getStatus(request).value()); Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); return new ModelAndView("error/500", model); } /** * 定義500的錯誤JSON信息 * @param request * @return */ @RequestMapping(value = "500") @ResponseBody public ResponseEntity<Map<String, Object>> error500(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); HttpStatus status = getStatus(request); return new ResponseEntity<Map<String, Object>>(body, status); } /** * Determine if the stacktrace attribute should be included. * @param request the source request * @param produces the media type produced (or {@code MediaType.ALL}) * @return if the stacktrace attribute should be included */ protected boolean isIncludeStackTrace(HttpServletRequest request, MediaType produces) { ErrorProperties.IncludeStacktrace include = this.serverProperties.getError().getIncludeStacktrace(); if (include == ErrorProperties.IncludeStacktrace.ALWAYS) { return true; } if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) { return getTraceParameter(request); } return false; } /** * 獲取錯誤的信息 * @param request * @param includeStackTrace * @return */ private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { RequestAttributes requestAttributes = new ServletRequestAttributes(request); return this.errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace); } /** * 是否包含trace * @param request * @return */ private boolean getTraceParameter(HttpServletRequest request) { String parameter = request.getParameter("trace"); if (parameter == null) { return false; } return !"false".equals(parameter.toLowerCase()); } /** * 獲取錯誤編碼 * @param request * @return */ private HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (Integer) request .getAttribute("javax.servlet.error.status_code"); if (statusCode == null) { return HttpStatus.INTERNAL_SERVER_ERROR; } try { return HttpStatus.valueOf(statusCode); } catch (Exception ex) { return HttpStatus.INTERNAL_SERVER_ERROR; } } /** * 實現錯誤路徑,暫時無用 * @see ExceptionMvcAutoConfiguration#containerCustomizer() * @return */ @Override public String getErrorPath() { return ""; } }
總結
第一步,通過定義containerCustomizer,重寫定義了異常處理對應的視圖。目前定義了404和500,可以繼續擴展。
第二步,重寫BasicErrorController,當然可以直接定義一個普通的controller類,直接實現第一步定義的視圖的方法。重寫的目的是重用ErrorAttributes。這樣在頁面,直接可以獲取到status,message,exception,trace等內容。
如果僅僅是把異常處理的視圖作為靜態頁面,不需要看到異常信息內容的話,直接第一步后,再定義error/404,error/500等靜態視圖即可。
ErrorController根據Accept頭的內容,輸出不同格式的錯誤響應。比如針對瀏覽器的請求生成html頁面,針對其它請求生成json格式的返回
上述就是小編為大家分享的Springboot項目中如何實現異常處理自定義了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。