springboot怎么返回404_深度分析:SpringBoot異常捕獲與封裝處理,看完你學會了嗎?...

4ac284dd3746d36312d39edbbf17cfd4.png

簡介

日常開發過程中,難免有的程序會因為某些原因拋出異常,而這些異常一般都是利用try ,catch的方式處理異常或者throw,throws的方式拋出異常不管。這種方法對于程序員來說處理也比較麻煩,對客戶來說也不太友好,所以我們希望既能方便程序員編寫代碼,不用過多的自己去處理各種異常編寫重復的代碼又能提升用戶的體驗,這時候全局異常處理就顯得很重要也很便捷了,是一種不錯的選擇。

全網獨家Spring/Cloud/MVC/Boot,腦圖+面試+進階,就問你服不服??zhuanlan.zhihu.com
379aac3243c13901b64a113867f25152.png

一、 全局異常捕獲與處理

Springboot對于異常的處理做了不錯的支持,它提供了兩個可用的注解。

@ControllerAdvice:用來開啟全局的異常捕獲

@ExceptionHandler:說明捕獲哪些異常,對哪些異常進行處理。

@ControllerAdvice
public class MyExceptionHandler {@ExceptionHandler(value =Exception.class)public String exceptionHandler(Exception e){System.out.println("發生了一個異常"+e);return e.getMessage();}
}

上面這段代碼的意思是,只要是代碼運行過程中有異常就會進行捕獲,并輸出出這個異常。然后我們隨便編寫一個會發生異常的代碼,測試出來的異常是這樣的。

d43d1928cd5cfb33baeb6c3035ae06d5.png

這對于前后端分離來說并不好,前后端分離之后唯一的交互就是json了,我們也希望將后端的異常變成json返回給前端處理,所以就需要統一結果返回和統一異常處理。

二、統一結果返回與統一異常

Result類:封裝返回結果。

public class Result<T> {private Integer code;//狀態碼private String message;//提示消息private T data;//數據public Result() {}/*** @param code 響應碼* @param message 響應信息*/public Result(Integer code, String message) {this.code = code;this.message = message;}/*** @param code 響應碼* @param message 響應信息* @param data 數據*/public Result(Integer code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** @param resultEnum 自定義枚舉類,包含 code 和 message*/public Result(ResultEnum resultEnum) {this.code = resultEnum.getCode();this.message = resultEnum.getMessage();}/*** @param resultEnum 自定義枚舉類,包含 code 和 message* @param data 數據*/public Result(ResultEnum resultEnum, T data) {this.code = resultEnum.getCode();this.message = resultEnum.getMessage();this.data = data;}/*** 自定義異常返回的結果* @param definitionException 自定義異常處理類* @return 返回自定義異常*/public static Result<Object> defineError(DefinitionException definitionException) {return new Result<>(definitionException.getErrorCode(), definitionException.getErrorMessage());}/*** 其他異常處理方法返回的結果* @param resultEnum 自定義枚舉類,包含 code 和 message* @return 返回其他異常*/public static Result<Object> otherError(ResultEnum resultEnum) {return new Result<>(resultEnum);}//這里寫get和set方法
}

注意:其中省略了get,set方法。

ResultEnum:自定義枚舉類。

public enum ResultEnum {// 數據操作定義SUCCESS(200, "成功"),TIME_OUT(130, "訪問超時"),NO_PERMISSION(403, "拒絕訪問"),NO_AUTH(401, "未經授權訪問"),NOT_FOUND(404, "無法找到資源"),METHOD_NOT_ALLOWED(405, "不支持當前請求方法"),SERVER_ERROR(500, " 服務器運行異常"),NOT_PARAM(10001, "參數不能為空"),NOT_EXIST_USER_OR_ERROR_PASSWORD(10002, "該用戶不存在或密碼錯誤"),NOT_PARAM_USER_OR_ERROR_PASSWORD(10003, "用戶名或密碼為空");;/*** 響應碼*/private final Integer code;/*** 響應信息*/private final String message;/*** 有參構造* @param code  響應碼* @param message 響應信息*/ResultEnum(Integer code, String message) {this.code = code;this.message = message;}public Integer getCode() {return code;}public String getMessage() {return message;}
}

注意:枚舉類中定義了常見的錯誤碼以及錯誤的提示信息。這里我們就定義好了統一的結果返回,其中里面的靜態方法是用來當程序異常的時候轉換成異常返回規定的格式。

DefinitionException:自定義異常處理類。

//@ControllerAdvice+@ResponseBody,開啟全局的異常捕獲,返回JSON
@RestControllerAdvice 
public class GlobalExceptionHandler {/*** 處理自定義異常* @return Result* @ExceptionHandler 說明捕獲哪些異常,對那些異常進行處理。*/@ExceptionHandler(value = DefinitionException.class)public Result<Object> customExceptionHandler(DefinitionException e) {return Result.defineError(e);}/*** 處理其他異常* @return Result*/@ExceptionHandler(value = Exception.class)public Result<Object> exceptionHandler(Exception e) {return Result.otherError(ErrorEnum.INTERNAL_SERVER_ERROR);}
}

說明:將對象解析成json,是為了方便前后端的交互。

三、代碼測試與結果

測試類

ResultController:測試的controller類

@RestController
public class ResultController {//獲取學生信息@GetMapping("/student")public Result<Student> getStudent() {Student student = new Student();student.setId(1);student.setAge(18);student.setName("XuWwei")return new Result<>(ResultEnum.SUCCESS, student);}//自定義異常處理@RequestMapping("/getDeException")public Result<Object> DeException() {throw new DefinitionException(400, "我出錯了");}//其他異常處理@RequestMapping("/getException")public Result Exception(){Result result = new Result();int a=1/0;return result;}

Student:學生類

public class Student {/*** 唯一標識id*/private Integer id;/*** 姓名*/private String name;/*** 年齡*/private Integer age;
}

注意:其中省略了get,set方法。

測試結果

啟動項目,一個一個測試

  1. 正常測試

6487fb9f891a86a740d7f90d1febc956.png

可以看到數據是正常返回json,沒有異常。

  1. 自定義異常

eb1b3a219eb10d06ae0412dc0558ae59.png

可以看到這個自定義的異常被捕獲到了,并且返回了一個json。

  1. 其他異常

4ba61124a6dade205e173242981328ba.png

可以看到這個異常被捕獲到了,并且返回了一個json。

注意:這種方法是不能處理404異常的,捕獲不到。

四、404異常特殊處理

1、修改配置文件

? 默認情況下,SpringBoot是不會拋出404異常的,所以**@ControllerAdvice**也不能捕獲到404異常。我們可以通過配置文件來讓這個注解能捕獲到404異常,在application.properties中添加以下配置:

#當發現404異常時直接拋出異常
spring.mvc.throw-exception-if-no-handler-found=true
#關閉默認的靜態資源路徑映射,這樣404不會跳轉到默認的頁面
spring.resources.add-mappings=false

但是關閉默認的靜態資源路徑映射會讓靜態資源訪問出現問題,也就是不適合前后端一體的情況。

但是我們可以手動配置靜態資源路徑映射,就能正常訪問靜態資源了。

@Configuration
public class ResourceConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//可以訪問localhost:8080/static/images/image.jpgregistry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");}
}

2、修改error跳轉路徑

? 關閉默認的靜態資源路徑映射顯然不太合理,可能會導致其他的錯誤發生,所以也可以通過修改默認錯誤頁面的跳轉路徑來達到我們的目的。

在GlobalExceptionHandler類中添加NotFoundExceptionHandler類,這個類繼承了ErrorController,可以重寫error的跳轉路徑

//處理404NotFoundException
@Controller
class NotFoundExceptionHandler implements ErrorController {//設置錯誤頁面路徑@Overridepublic String getErrorPath() {return "/error";}//當訪問error路徑時,返回一個封裝的異常的Json@RequestMapping("/error")@ResponseBodypublic Result<Object> error() {return Result.otherError(ResultEnum.NOT_FOUND);}
}

五、拓展異常類

? GlobalExceptionHandler的exceptionHandler方法將所有的異常統一返回500系統錯誤,這不符合我們的設想,所以我們可以通過判斷異常的類型,來返回不同的值。

將exceptionHandler改成以下代碼:

/*** 處理其他異常* @return Result*/
@ExceptionHandler(value = Exception.class)
public Result<Object> exceptionHandler(Exception e) {if (e instanceof NullPointerException){//捕獲空指針異常return Result.otherError(ResultEnum.NOT_PARAM);}else if (e instanceof IllegalAccessException){//非法訪問異常return Result.otherError(ResultEnum.NO_PERMISSION);} else{return Result.otherError(ResultEnum.SERVER_ERROR);}
}

注意:更多異常可以通過else if來細分。

六、總結

?springboot的異常處理,需要通過@ControllerAdvice注解以及 @ExceptionHandler注解,來攔截所有的異常,并通過一個封裝返回值返回。但是,這兩個注解無法捕獲404NotFound異常,因為SpringBoot默認是不會拋出404異常的,所以要通過繼承ErrorController來修改404異常的跳轉路徑,達到捕獲404異常的目的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530632.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530632.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530632.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

新生成長記;關于zzulioj1056,幸運數字

剛剛接觸代碼的我&#xff0c;對計算機愈來愈好奇&#xff0c;開學的兩個月&#xff0c;幾乎沒看書只顧著做題&#xff0c;當然&#xff0c;不會就百度&#xff0c;或者看大佬的博客&#xff0c;這些都是好東西&#xff0c;實在看不懂的&#xff0c;就拿著跑去問學長&#xff0…

獲取form表單_【第1535期】前端 Form 的表單的一個通用解決方案

前言今日早讀文章由阿里布達投稿分享。布達&#xff0c;Alibaba Fusion項目組的。花名潕量。主要專注在設計系統、組件、可視化搭建這個領域正文從這開始&#xff5e;&#xff5e;Fusion Next - Form 表單解決方案前端的Form 表單主要用于解決數據獲取、數據校驗、數據賦值 這三…

c語言表白用代碼(1)

不多說&#xff0c;直接上代碼&#xff0c;有用拿走&#xff0c;侵權立刪。 希望大家盡早找到自己的另一半。 #include <stdio.h> #include <math.h> #include <stdlib.h> #define I 20 #define R 340 #include <string.h> int main() {char answer[4…

react取消捕獲_React學習筆記(三)

React學習筆記&#xff08;三&#xff09;&#xff0c;組件的生命周期React中組件也有生命周期&#xff0c;也就是說也有很多鉤子函數供我們使用, 組件的生命周期&#xff0c;我們會分為四個階段&#xff0c;初始化、運行中、銷毀、錯誤處理(16.3之后)初始化在組件初始化階段會…

zzulioj1111: 多個整數的逆序輸出(函數專題)

1111: 多個整數的逆序輸出&#xff08;函數專題&#xff09;時間限制: 1 Sec 內存限制: 128 MB 提交: 3521 解決: 2617 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入n和n個整數&#xff0c;以與輸入順序相反的順序輸出這n個整數。要求不使用數組&#xff0c;而使用遞歸…

快捷鍵_AutoCAD 2021中的默認快捷鍵、新建或編輯快捷鍵

文&#xff1a;CAD鐘日銘。歡迎關注和點贊支持。在使用AutoCAD進行制圖的過程中&#xff0c;掌握一些快捷鍵會提高操作效率。所謂的快捷鍵是指用于啟動命令的鍵組合。例如&#xff0c;按CtrlN組合鍵(快捷鍵)新建圖形文件&#xff0c;按 CtrlO組合鍵可打開圖形文件&#xff0c;按…

1112: 進制轉換(函數專題)

1112: 進制轉換&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 3448 解決: 2599 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入一個十進制整數n&#xff0c;輸出對應的二進制整數。常用的轉換方法為“除2取余&#xff0c;倒序排列”。將一個…

出現畫面抖動_連續抖動20小時!虎門大橋橋面如波浪翻滾,專家:個人感覺沒問題...

前兩天(5月5日)&#xff0c;虎門大橋橋面出現如波浪翻滾的起伏&#xff0c;引發廣泛的關注&#xff1a;次日&#xff0c;廣東交通集團通報&#xff0c;虎門大橋震動是渦振現象&#xff0c;懸索橋結構安全。專家初步判斷此次渦振和橋上設置水馬有關。但直到6日早上11時&#xff…

1098: 復合函數求值(函數專題)

1098: 復合函數求值&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 5545 解決: 4335 [提交] [狀態] [討論版] [命題人:admin] 題目描述 求復合函數F(G(x))&#xff0c;其中函數F(x)|x-3||x1|&#xff0c;函數G(x)x^2-3x。要求編寫函數funF()和funG(…

安全模式 提權_記一次滲透挖洞提權實戰

摘要&#xff1a;這是一次挖掘cms通用漏洞時發現的網站&#xff0c;技術含量雖然不是很高&#xff0c;但是也拿出來和大家分享一下吧&#xff0c;希望能給一部分人帶來收獲。0x01 進入后臺在通過googlehack語法挖掘beescms時發現了這個站點利用網上的payload&#xff0c;在/mx_…

win7無法連接打印機拒絕訪問_“Windows無法連接打印機,操作失敗,錯誤為0x000003e3”...

請求大家幫助&#xff0c;昨天在共享打印機時出現“Windows無法連接打印機&#xff0c;操作失敗&#xff0c;錯誤為0x000003e3”。在百度百科查詢的資料修改了都不行(在不重裝系統前提下&#xff0c;聯想臺式機都是win732位系統)&#xff0c;給大家一一列舉&#xff0c;請求廣大…

1108: 打印數字圖形(函數專題)

1108: 打印數字圖形&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 4040 解決: 2786 [提交] [狀態] [討論版] [命題人:admin] 題目描述 從鍵盤輸入一個整數n(1≤n≤9),打印出指定的數字圖形。要求在程序中定義并調用如下函數&#xff1a;PrintSpace…

類型全部為string_python小講堂丨學了這么久的,這6種基本數據類型你真的理解了嗎...

哈嘍&#xff0c;大家好&#xff0c;歡迎來到python小講堂&#xff0c;間歇性的努力&#xff0c;會導致持續性的一事無成&#xff0c;即使今天是除夕&#xff0c;我們也不能懈怠啊&#xff0c;今天我給大家帶來的是關于python的6種基本數據類型的深入講解&#xff0c;話不多說讓…

1105: 判斷友好數對(函數專題)

1105: 判斷友好數對&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 5790 解決: 2629 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入兩個正整數m和n&#xff0c;順序輸出m到n之間的所有友好數對。 如果兩個整數的所有正因子之和&#xff08;…

防抖 節流_【前端面試】節流與防抖

我們用兩張圖表示什么是節流和防抖。防抖節流由圖可見&#xff0c;防抖的意思是&#xff0c;當用戶在一段時間內連續頻繁的試圖執行一個函數的時候&#xff0c;只有最后一次&#xff0c;函數被真正的執行。節流的意思是&#xff0c;當用戶在某一個時刻執行了一次函數的時候&…

沒數據時y軸不顯示_Matplotlib數據可視化

1.Matplotlib介紹什么是MatplotlibMatplotlib是一個Python的繪圖庫&#xff0c;它可與 NumPy 一起使用&#xff0c;可以代替MMatplotlib安裝由于Matplotlib是第三方庫&#xff0c;所以我們需要安裝它才可以使用。注意&#xff0c;Matplotlib3.0要求python3版本才可安裝使用。安…

1099: 角谷猜想(多實例測試)

1099: 角谷猜想&#xff08;多實例測試&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 5930 解決: 3888 [提交] [狀態] [討論版] [命題人:admin] 題目描述 任何一個自然數&#xff0c;如果是偶數&#xff0c;就除以2&#xff0c;如果是奇數&#xff0c;就乘以3再加1。最…

python軟件運行界面_python運行界面 python的圖形用戶界面怎么運行

為什么用Python開發界面應用程序1)wxWidgets是一個比MFC優雅的庫&#xff0c;TortoiseCVS用wxWidges而不用MFC&#xff0c;就是因為wxWidgets好用&#xff0c;而不是為了可以移植。 2)Python的面向對象腳本語言編程適合快速界面開發 3)Python在服務器端和客戶端都非常有前途&am…

1100: 求組合數(函數專題)

1100: 求組合數&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 6264 解決: 4653 [提交] [狀態] [討論版] [命題人:admin] 題目描述 馬上要舉辦新生程序設計競賽了&#xff0c;與以往不同的是&#xff0c;本次比賽以班為單位&#xff0c;為了全面衡量…

python畫圖隱藏畫筆_python畫圖

轉至&#xff1a;https://blog.csdn.net/weixin_43943977/article/details/1026913921、灰色櫻花樹from turtle import *from random import *from math import *def tree(n,l):pd()#下筆#陰影效果t cos(radians(heading()45))/80.25pencolor(t,t,t)pensize(n/3)forward(l)#畫…