1. 程式人生 > >Spring Boot 錯誤處理機制及定製(五)

Spring Boot 錯誤處理機制及定製(五)

1、SpringBoot預設的錯誤處理機制

預設效果:

​ 1)、瀏覽器,返回一個預設的錯誤頁面

這裡寫圖片描述

瀏覽器傳送請求的請求頭:

這裡寫圖片描述

​ 2)、如果是其他客戶端,預設響應一個json資料

這裡寫圖片描述
這裡寫圖片描述

原理:

​ 可以參照ErrorMvcAutoConfiguration;錯誤處理的自動配置;

給容器中添加了以下元件

​ 1、DefaultErrorAttributes:

幫我們在頁面共享資訊;
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
		boolean
includeStackTrace) { Map<String, Object> errorAttributes = new LinkedHashMap<String, Object>(); errorAttributes.put("timestamp", new Date()); addStatus(errorAttributes, requestAttributes); addErrorDetails(errorAttributes, requestAttributes, includeStackTrace); addPath(errorAttributes,
requestAttributes); return errorAttributes; }

​ 2、BasicErrorController:處理預設/error請求

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
   
   @RequestMapping(produces = "text/html")//產生html型別的資料;瀏覽器傳送的請求來到這個方法處理
public
ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes( request, isIncludeStackTrace(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); //去哪個頁面作為錯誤頁面;包含頁面地址和頁面內容 ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView == null ? new ModelAndView("error", model) : modelAndView); } @RequestMapping @ResponseBody //產生json資料,其他客戶端來到這個方法處理; public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); HttpStatus status = getStatus(request); return new ResponseEntity<Map<String, Object>>(body, status); }

​ 3、ErrorPageCustomizer:

這裡寫圖片描述

	@Value("${error.path:/error}")
	private String path = "/error";  系統出現錯誤以後來到error請求進行處理;(web.xml註冊的錯誤頁面規則)

​ 4、DefaultErrorViewResolver:

這裡寫圖片描述

@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status,
                                    Map<String, Object> model) {
   ModelAndView modelAndView = resolve(String.valueOf(status), model);
   if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
       modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
   }
   return modelAndView;
}

private ModelAndView resolve(String viewName, Map<String, Object> model) {
   //預設SpringBoot可以去找到一個頁面?  error/404
   String errorViewName = "error/" + viewName;

   //模板引擎可以解析這個頁面地址就用模板引擎解析
   TemplateAvailabilityProvider provider = this.templateAvailabilityProviders
       .getProvider(errorViewName, this.applicationContext);
   if (provider != null) {
       //模板引擎可用的情況下返回到errorViewName指定的檢視地址
       return new ModelAndView(errorViewName, model);
   }
   //模板引擎不可用,就在靜態資原始檔夾下找errorViewName對應的頁面   error/404.html
   return resolveResource(errorViewName, model);
}

​ 步驟:

​ 一但系統出現4xx或者5xx之類的錯誤;ErrorPageCustomizer就會生效(定製錯誤的響應規則);就會來到/error請求;就會被BasicErrorController處理;

​ 1)響應頁面;去哪個頁面是由DefaultErrorViewResolver解析得到的;

protected ModelAndView resolveErrorView(HttpServletRequest request,
     HttpServletResponse response, HttpStatus status, Map<String, Object> model) {
   //所有的ErrorViewResolver得到ModelAndView
  for (ErrorViewResolver resolver : this.errorViewResolvers) {
     ModelAndView modelAndView = resolver.resolveErrorView(request, status, model);
     if (modelAndView != null) {
        return modelAndView;
     }
  }
  return null;
}

2、如果定製錯誤響應:

2、1 如何定製錯誤的頁面;

1)、有模板引擎的情況下;error/狀態碼; 【將錯誤頁面命名為 錯誤狀態碼.html 放在模板引擎資料夾裡面的 error資料夾下】,發生此狀態碼的錯誤就會來到 對應的頁面;

​ 我們可以使用4xx和5xx作為錯誤頁面的檔名來匹配這種型別的所有錯誤,精確優先(優先尋找精確的狀態碼.html);

​ 頁面能獲取的資訊;

timestamp:時間戳

status:狀態碼

error:錯誤提示

exception:異常物件

message:異常訊息

errors:JSR303資料校驗的錯誤都在這裡

​ 2)、沒有模板引擎(模板引擎找不到這個錯誤頁面),靜態資原始檔夾下找;

​ 3)、以上都沒有錯誤頁面,就是預設來到SpringBoot預設的錯誤提示頁面;

這裡寫圖片描述

2)、如何定製錯誤的json資料;

​ 1)、自定義異常處理&返回定製json資料;

@ControllerAdvice
public class MyExceptionHandler {

    @ResponseBody
    @ExceptionHandler(UserNotExistException.class)
    public Map<String,Object> handleException(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        return map;
    }
}
//沒有自適應效果...

​ 2)、轉發到/error進行自適應響應效果處理

 @ExceptionHandler(UserNotExistException.class)
    public String handleException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        //傳入我們自己的錯誤狀態碼  4xx 5xx,否則就不會進入定製錯誤頁面的解析流程
        /**
         * Integer statusCode = (Integer) request
         .getAttribute("javax.servlet.error.status_code");
         */
        request.setAttribute("javax.servlet.error.status_code",500);
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        //轉發到/error
        return "forward:/error";
    }

3)、將我們的定製資料攜帶出去;

出現錯誤以後,會來到/error請求,會被BasicErrorController處理,響應出去可以獲取的資料是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)規定的方法);

​ 1、完全來編寫一個ErrorController的實現類【或者是編寫AbstractErrorController的子類】,放在容器中;

​ 2、頁面上能用的資料,或者是json返回能用的資料都是通過errorAttributes.getErrorAttributes得到;

​ 容器中DefaultErrorAttributes.getErrorAttributes();預設進行資料處理的;

自定義ErrorAttributes

//給容器中加入我們自己定義的ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {

   @Override
   public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
       Map<String, Object> map = super.getErrorAttributes(requestAttributes, includeStackTrace);
       map.put("company","hfbin");
       Map<String,Object> ext = (Map<String, Object>) requestAttributes.getAttribute("ext", 0);
       return map;
   }
}

(Map <String, Object>) requestAttributes.getAttribute(“ext”, 0);

需要傳兩個引數 第二個是請求型別,看下面原始碼:

這裡寫圖片描述

轉發到/error進行自適應響應效果處理,需要將資料放到request中

@ExceptionHandler(UserNotExistException.class)
   public String handleException(Exception e, HttpServletRequest request){
       Map<String,Object> map = new HashMap<>();
       //傳入我們自己的錯誤狀態碼  4xx 5xx,否則就不會進入定製錯誤頁面的解析流程
       request.setAttribute("javax.servlet.error.status_code",500);
       map.put("code","user.notexist");
       map.put("message",e.getMessage());
        request.setAttribute("ext",map);
       //轉發到/error
       return "forward:/error";
   }

最終的效果:響應是自適應的,可以通過定製ErrorAttributes改變需要返回的內容,

這裡寫圖片描述

相關推薦

Spring Boot 錯誤處理機制定製

1、SpringBoot預設的錯誤處理機制 預設效果: ​ 1)、瀏覽器,返回一個預設的錯誤頁面 瀏覽器傳送請求的請求頭: ​ 2)、如果是其他客戶端,預設響應一個json資料 原理: ​ 可以參照ErrorMvcAutoConfiguration

Spring Boot15Spring Boot錯誤處理機制

1、Spring Boot預設的錯誤處理機制 如果是瀏覽器,則返回一個預設的錯誤頁面: 如果是其他測試工具,如Postman,則返回一個json資料: 原理: ​ 可以參照ErrorMvcAutoConfiguration,錯誤處理的自動配置

Spring boot錯誤處理機制

錯誤處理機制 當程式發生錯誤的時候 瀏覽器訪問 Spring boot提供了一個預設的錯誤頁面 包括錯誤狀態碼、錯誤型別、提示訊息、時間 客戶端訪問 當程式發生錯誤的時候 預設響應了

有關PHP異常和錯誤處理機制的思考

通過上篇文章呢,咱們對於PHP異常的定義、捕獲、處理等方面有了簡單的一個概念,這次呢,咱們就來看下關於異常的同胞兄弟,錯誤,以及錯誤的一個處理機制。 我們要知道,PHP中,錯誤處理,比異常處理,更加重要和凸顯價值,咱們之前的文章呢,已經把錯誤的概念介紹過了,現在,咱們就相比較於異常,來給錯誤

有關PHP異常和錯誤處理機制的思考

我們從一門語言的層面上來看的話,這個語言通常具有很多的錯誤處理的一個模式,但是這些個錯誤處理模式,往往就是建立在約定俗成的基礎上,也可以說,這些錯誤都是可以預知的。 但是在大型的一個專案或者說系統裡,如果我們每次呼叫一個功能模組的時候,都去逐一檢測我們這個模組中肯能存在的錯誤,很明顯的就會看

spring boot 2.0 源碼分析

pen div shutdown down etc messages servle started fec 在上一篇文章中我們詳細分析了spring boot是如何準備上下文環境的,今天我們來看一下run函數剩余的內容。還是先把run函數貼出來: /**

Spring Boot-錯誤處理自定義全域性異常處理機制

正常的Web應用開發時,需要考慮到應用執行發生異常時或出現錯誤時如何來被處理,例如捕獲必要的異常資訊,記錄日誌方便日後排錯,友好的使用者響應輸出等等。 當然應用發生錯誤,有可能是應用自身的問題,也有可能是客戶端操作的問題。 Spring Boot預設提供了一種錯誤處理機制。 預設錯誤處理機制

七、Spring Boot 錯誤處理原理 & 定製錯誤頁面

【1】錯誤預設處理機制、 1)瀏覽器,返回一個預設的錯誤頁面 請求頭: 2) 其他客戶端訪問,預設響應 JSON 資料 請求頭: 為什麼會產生這樣的預設效果? 原理:可以參照 ErrorMvcAutoConfiguration;錯誤處理的自動配置; Er

Spring boot錯誤處理原理

錯誤處理原理 ErrorMvcAutoConfiguration 錯誤處理自動配置 自動配置 給容器中添加了以下元件 1、DefaultErrorAttributes 2、BasicErrorController 3、ErrorPageC

Spring boot+Security OAuth2 爬坑日記4自定義異常處理

為了方便與前端更好的互動,服務端要提供友好統一的資訊返回格式,(他好我也好 ->_-> ),Spring Security OAuth2 提供了自定義異常的入口;我們需要做的就是實現對應的介面,然後將實現的類配置到對應的入口即可。預設的資訊返回格式

SpringBoot之錯誤處理機制以及定製錯誤資訊

一、SpringBoot預設的錯誤處理機制 預設效果: 1)、瀏覽器,返回一個預設的錯誤頁面 瀏覽器傳送請求的請求頭: 2)、如果是其他客戶端,預設響應一個json資料 原理: 可以參照ErrorMvcAutoConfigurat

Spring Boot原始碼分析】@EnableAutoConfiguration註解@AutoConfigurationImportSelector註解的處理

一、概述 @EnableAutoConfiguration註解是Spring Boot中配置自動裝載的總開關。本文將從@EnableAutoConfiguration入手,嘗試通過原始碼分析增強對Spring Boot的理解。   所用版本:Spring Boot 2.2.0.M5 + Spring

Spring Boot 入門之持久層篇

imp 配置文件 bat catch map ann 文件 save values 原文地址:Spring Boot 入門之持久層篇(三) 博客地址:http://www.extlight.com 一、前言 上一篇《Spring Boot 入門之 Web 篇(二)》介紹

spring boot-mybatis三種動態sql5

內部 轉換成 ava .get bat class ide div upd 腳本sql XML配置方式的動態SQL我就不講了,有興趣可以自己了解,下面是用<script>的方式把它照搬過來,用註解來實現。適用於xml配置轉換到註解配置 @Select("&l

徹底弄懂HTTP緩存機制原理轉載

一次 chrom https 分開 res 技術 觸發 明顯 總結 https://www.cnblogs.com/chenqf/p/6386163.html 前言 Http 緩存機制作為 web 性能優化的重要手段,對於從事 Web 開發的同學們來說,應該是知識體系庫中的

spring boot security 防止使用者重複登入原創

原理:在認證成功通過後,在顯示登入成功頁面之前,也就是在SavedRequestAwareAuthenticationSuccessHandler類中操作。 新增一個集合sessionMap 用於儲存認證成功的會話,鍵名為會話ID, 每次有使用者登入認證通過都要判斷一下是否重複登入

Spring boot+Security OAuth2 爬坑日記2授權碼模式升級篇

1. 開發環境和本專案用到的框架 接著上一篇Spring boot+Security OAuth2 爬坑日記(1)授權碼模式部落格中的內容,上篇介紹了基本的開發環境,系統以及jdk版本等,本篇再來詳細介紹下專案中用到的框架和相關類庫。 框架/類庫/資

Spring boot+Security OAuth2 爬坑日記1授權碼模式

OAuth2 OAuth 關於授權的開放網路標準,關於OAuth2的知識,參考OAuth2.0 和 理解OAuth 2.0-阮一峰 四種授權模式 授權碼模式 (功能最完整,流程最嚴密) 密碼模式 客戶端模式 簡化模式 授權碼模式

Spring Boot簡明教程之資料訪問:MyBatis

Spring Boot簡明教程之資料訪問(三):MyBatis 文章目錄 Spring Boot簡明教程之資料訪問(三):MyBatis MyBatis簡介 使用註解進行資料訪問 專案建立 專案目錄

Spring Boot簡明教程之資料訪問:JPA(超詳細)

Spring Boot簡明教程之資料訪問(二):JPA(超詳細) 文章目錄 Spring Boot簡明教程之資料訪問(二):JPA(超詳細) 建立專案 Spring Data簡介 JPA簡介 Spring Data 與JP