SpringBoot圖文教程15—項目異常怎麼辦?「跳轉404錯誤頁面」「全局異常捕獲」

来源:https://www.cnblogs.com/bingyang-py/archive/2020/03/12/12482680.html
-Advertisement-
Play Games

有天上飛的概念,就要有落地的實現 概念十遍不如代碼一遍,朋友,希望你把文中所有的代碼案例都敲一遍 先贊後看,養成習慣 SpringBoot 圖文教程系列文章目錄 1. "SpringBoot圖文教程1—SpringBoot+Mybatis 環境搭建" 2. "SpringBoot圖文教程2—日誌的使 ...


有天上飛的概念,就要有落地的實現

  • 概念十遍不如代碼一遍,朋友,希望你把文中所有的代碼案例都敲一遍

  • 先贊後看,養成習慣

SpringBoot 圖文教程系列文章目錄

  1. SpringBoot圖文教程1—SpringBoot+Mybatis 環境搭建
  2. SpringBoot圖文教程2—日誌的使用「logback」「log4j」
  3. SpringBoot圖文教程3—「‘初戀’情結」集成Jsp
  4. SpringBoot圖文教程4—SpringBoot 實現文件上傳下載
  5. SpringBoot圖文教程5—SpringBoot 中使用Aop
  6. SpringBoot圖文教程6—SpringBoot中過濾器的使用
  7. SpringBoot圖文教程7—SpringBoot攔截器的使用姿勢這都有
  8. SpringBoot圖文教程8—SpringBoot集成MBG「代碼生成器」
  9. SpringBoot圖文教程9—SpringBoot 導入導出 Excel 「Apache Poi」
  10. SpringBoot圖文教程10—模板導出|百萬數據Excel導出|圖片導出「easypoi」
  11. SpringBoot圖文教程11—從此不寫mapper文件「SpringBoot集成MybatisPlus」
  12. SpringBoot圖文教程12—SpringData Jpa的基本使用
  13. SpringBoot圖文教程13—SpringBoot+IDEA實現代碼熱部署
  14. SpringBoot圖文教程14—阿裡開源EasyExcel「為百萬數據讀寫設計」

前言

本文教程示例代碼見碼雲倉庫:https://gitee.com/bingqilinpeishenme/boot-demo

異常處理在Java中是一種很常規的操作,在代碼中我們常用的方法是try catch或者上拋異常。

但是,如果Controller發生異常了怎麼辦?業務層的異常可以在Controller捕獲,Controller拋出的異常怎麼捕獲?SpringMvc的異常怎麼捕獲?

這個時候常見的操作有兩種:

  1. 跳轉錯誤頁面,例如:找不到路徑的時候跳轉404,代碼報錯的時候跳轉500等
  2. 響應統一的報錯信息,使用Result對象(自定義的實體類)封裝錯誤碼,錯誤描述信息響應【分散式服務調用的時候推薦使用】

今天我們就簡單的來講解一下SpringBoot中如何進行異常處理,跳轉404或者封裝錯誤信息響應。

跳轉錯誤頁面

SpringBoot 錯誤頁面的預設配置

在SpringBoot中 error page錯誤頁面是有預設配置的,預設配置是這樣

  • 如果在static目錄中存在error文件夾,並且文件夾中存在400.html,或者500.html,出現對應的響應狀態的時候(404和500的使用),會跳轉到對應的頁面

  • 如果你使用的是webapp目錄,也是一樣的,只要在webapp目錄中存在400.jsp頁面(html也一樣),出現對應的響應狀態的時候(404和500的使用),會跳轉到對應的頁面

以上是預設配置,只要是SpringBoot的項目都會生效,接下來我們來測試一下

  1. 在static目錄下創建error文件夾,400.html以及500.html

  2. 寫一個會報錯的Controller方法 test500

  3. 啟動項目分別訪問一個不存在的路徑【測試】和訪問會報錯的Controller方法,效果如下

自定義錯誤頁面的配置

以上是SpringBoot關於錯誤頁面的預設配置,但是很多時候我們的需求比SpringBoot的預設配置要複雜很多,例如:404頁面不想放在error文件夾下,500錯誤的時候也不想跳轉頁面,而是響應給頁面一個json的數據等。

這個時候需要做的就是修改SpringBoot的預設配置了。

實現的目標:

  • 404的時候跳轉到static下的404頁面
  • 500的時候響應頁面一句話:“後臺錯誤 請聯繫管理員”

第一步:創建一個能夠響應 “後臺錯誤 請聯繫管理員” 這句話的Controller方法,將404頁面放在static下麵【如果是webapp也一樣】

第二步:創建錯誤頁面的配置類,修改預設的配置


/**
 * 錯誤頁面配置
 *
 * 繼承錯誤頁面註冊器 ErrorPageRegistrar
 */
@Configuration
public class ErrorConfig implements ErrorPageRegistrar {
    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        /**
         * 配置錯誤頁面
         *
         * ErrorPage 有兩個參數
         * 參數1 響應狀態碼  NOT_FOUND 404  INTERNAL_SERVER_ERROR 500
         * 參數2 出現響應狀態碼的時候的跳轉路徑  可以自定義跳轉路徑
         */
        ErrorPage error404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
        ErrorPage error500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/testData");

        /**
         * 將ErrorPage 註冊到註冊器中
         */
        registry.addErrorPages(error404,error500);

    }
}

第三步:啟動項目,可以看到如下效果

訪問不存在的路徑,跳轉404頁面

訪問 http://localhost:8802/test500 效果如下:

以上就是跳轉404和統一響應數據的操作,但是還有問題,什麼問題呢?

以上的操作實際上沒有針對異常進行捕獲,而是根據響應的狀態碼進行不同的處理的,那麼如果才能針對不同的異常進行捕獲呢?這就要用到全局異常捕獲了。

全局異常捕獲

還記得文章開頭說過的第二個場景嗎?使用Result對象(自定義的實體類)統一封裝異常狀態碼,異常信息,進行返回。通過全局異常捕獲就可以實現。

測試的要求是:

  • 捕獲自定義異常,封裝Result對象以json的格式響應
  • 捕獲自定義異常,跳轉到錯誤頁面

1.自定義異常

在應用開發過程中,除系統自身的異常外,不同業務場景中用到的異常也不一樣,很多時候需要自定義異常,所以我們自定義兩個異常,分別是:

  • ErrorReturnResultException 如果出現這個異常,就返回統一Result對象
  • ErrorReturnPageException 如果出現這個異常,就跳轉錯誤頁面

ErrorReturnResultException

package com.lu.bootexception.exception;

public class ErrorReturnResultException extends RuntimeException {
    /**
     * 錯誤碼
     */
    private int code;

    public ErrorReturnResultException() {

    }

    public ErrorReturnResultException(String message) {
        super(message);
    }
    public ErrorReturnResultException(String message, int code) {
        super(message);
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

ErrorReturnPageException

package com.lu.bootexception.exception;

public class ErrorReturnPageException extends RuntimeException {
    /**
     * 錯誤碼
     */
    private int code;


    public ErrorReturnPageException() {
    }

    public ErrorReturnPageException(String message, int code) {
        super(message);
        this.code = code;
    }

    public ErrorReturnPageException(String message) {
        super(message);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

2.自定義響應實體

定義返回的異常信息的格式,這樣異常信息風格更為統一

package com.lu.bootexception.exception;

import lombok.Data;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private int code;
    private String message;
}

3.全局異常捕獲實現

利用Spring的API定義一個全局異常處理的類,代碼和註釋如下:

package com.lu.bootexception.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @ControllerAdvice 增強Controller的註解 可以實現全局異常捕獲
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     *  @ExceptionHandler 指明要捕獲那個異常
     *  不加@ResponseBody  會使用視圖解析器跳轉頁面
     *  形參處是Exception 簡單來說就是會把捕獲到的異常通過形參傳入方法中
     */
    @ExceptionHandler(ErrorReturnPageException.class)
    public String errorReturnPageException(Exception e){
//        列印錯誤信息
        System.out.println(e.getMessage());
//        跳轉500頁面
        return "forward:/500.html";
    }

    /**
     * 捕獲  ErrorReturnResultException 異常
     * 通過 @ResponseBody 註解響應數據 會以json的格式響應
     */
    @ExceptionHandler(ErrorReturnResultException.class)
    @ResponseBody
    public Result errorReturnResultException(final Exception e) {
        ErrorReturnResultException exception = (ErrorReturnResultException) e;
        /**
         * Result 中可以寫入自定義的異常狀態碼
         */
        return new Result(5001, exception.getMessage());
    }

    /**
     * 捕獲  RuntimeException 異常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public Result runtimeExceptionHandler(final Exception e) {
        RuntimeException exception = (RuntimeException) e;
        /**
         * Result 中可以寫入自定義的異常狀態碼
         */
        return new Result(4004, exception.getMessage());
    }
}

代碼中用到的註解

  • @ControllerAdvice 捕獲拋出的異常,如果添加 @ResponseBody 返回信息則為JSON格式。
  • @RestControllerAdvice 相當於 @ControllerAdvice@ResponseBody 的結合體。
  • @ExceptionHandler 指明要捕獲那個異常

4.寫兩個測試方法 測試全局異常捕獲的效果

訪問 http://localhost:8802/testReturnPage 會跳轉錯誤頁面

訪問 http://localhost:8802/testReturnResult 會返回統一的json數據

總結

恭喜你完成了本章的學習,為你鼓掌!如果本文對你有幫助,請幫忙點贊,評論,轉發,這對作者很重要,謝謝。

讓我們再次回顧本文的學習目標

  • 掌握SpringBoot中異常處理的基本使用

要掌握SpringBoot更多的用法,請持續關註本系列教程。

求關註,求點贊,求轉發

歡迎關註本人公眾號:鹿老師的Java筆記,將在長期更新Java技術圖文教程和視頻教程,Java學習經驗,Java面試經驗以及Java實戰開發經驗。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當成員被靜態修飾後,就多了一種調用方式,除了可以被對象調用外,還可以直接被類名調用。 類名.靜態成員 static特點: 1.隨著類的載入而載入 靜態會隨著類的消失而消失,說明它的生命周期最長。 2.優先於類的對象存在 靜態先存在,對象後存在 3.被所有對象所共用 4.可以直接被類名所調用 沒有被s ...
  • 一、 ​解析available\skip\close\read(int[] a)方法以及使用read方法迴圈列印出所有的​內容。 package com.bjpowernode.java_learning; import java.io.*; public class D96_1_CircleRea ...
  • 前言 隨著DevOp的不斷流行,自動化測試慢慢成為Java開發者的關註點。因此,本文將分享10款優秀的單元測試框架和庫,它們可以幫助Java開發人員在其Java項目上編寫單元測試和集成測試。 1. JUnit 我絕對 不需要太多的介紹了。即使您是Java初學者,也可能聽說過它。它可以幫助您為Java ...
  • 背景 java程式員一般寫的是後端服務是JavaWeb類型的項目,主要包括Http介面和dubbo介面,Http介面一般採用的rest風格,那麼如何快速的對rest介面在第三方的測試框架上進行測試呢? rest assured框架是一個不錯的工具。好比軍人的三棱軍刺,如上圖。 使用之前,需要熟悉一下 ...
  • 給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和為目標值的那 兩個 整數,並返回他們的數組下標。 你可以假設每種輸入只會對應一個答案。但是,你不能重覆利用這個數組中同樣的元素。 示例: 給定 nums = [2, 7, 11, 15], target = 9 因為 num ...
  • 類由靜態到動態,會經歷運行時數據區這一步: 靜態編譯:把Java代碼編譯成位元組碼文件Class文件,它以靜態方式存在 類載入器:把Java位元組碼文件載入到記憶體中 【方法區】與【堆】是運行時數據區在所有線程間共用的,它們是存數據的地方 【虛擬機棧】,【本地方法棧】,【程式計數器】是運行時數據區線程私有 ...
  • 使用LinkedHashSet刪除arraylist中的重覆數據(有序) 使用HashSet去重(無序) 使用java8新特性stream進行List去重 利用List的contains方法迴圈遍歷 註:當數據元素是實體類時,需要額外重寫equals()和hashCode()方法。 例如: 以學號為 ...
  • 本人免費整理了Java高級資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分散式等教程,一共30G,需要自己領取。傳送門:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ 關 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...