chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

關(guān)于SpringBoot如何優(yōu)雅的全局異常處理

電子工程師 ? 來源:博客 ? 作者:虛無境 ? 2021-05-31 14:25 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

SpringBoot全局異常準(zhǔn)備說明:如果想直接獲取工程那么可以直接跳到底部,通過鏈接下載工程代碼。

開發(fā)準(zhǔn)備

環(huán)境要求JDK:1.8SpringBoot:1.5.17.RELEASE

首先還是Maven的相關(guān)依賴:

《properties》

《project.build.sourceEncoding》UTF-8《/project.build.sourceEncoding》

java.version》1.8《/java.version》

《maven.compiler.source》1.8《/maven.compiler.source》

《maven.compiler.target》1.8《/maven.compiler.target》

《/properties》

《parent》

《groupId》org.springframework.boot《/groupId》

《artifactId》spring-boot-starter-parent《/artifactId》

《version》1.5.17.RELEASE《/version》

《relativePath /》

《/parent》

《dependencies》

《!-- Spring Boot Web 依賴 核心 --》

《dependency》

《groupId》org.springframework.boot《/groupId》

《artifactId》spring-boot-starter-web《/artifactId》

《/dependency》

《!-- Spring Boot Test 依賴 --》

《dependency》

《groupId》org.springframework.boot《/groupId》

《artifactId》spring-boot-starter-test《/artifactId》

《scope》test《/scope》

《/dependency》

《dependency》

《groupId》com.alibaba《/groupId》

《artifactId》fastjson《/artifactId》

《version》1.2.41《/version》

《/dependency》

《/dependencies》

配置文件這塊基本不需要更改,全局異常的處理只需在代碼中實現(xiàn)即可。

代碼編寫

SpringBoot的項目已經(jīng)對有一定的異常處理了,但是對于我們開發(fā)者而言可能就不太合適了,因此我們需要對這些異常進行統(tǒng)一的捕獲并處理。SpringBoot中有一個ControllerAdvice的注解,使用該注解表示開啟了全局異常的捕獲,我們只需在自定義一個方法使用ExceptionHandler注解然后定義捕獲異常的類型即可對這些捕獲的異常進行統(tǒng)一的處理。

我們根據(jù)下面的這個示例來看該注解是如何使用吧。

示例代碼:

@ControllerAdvice

public class MyExceptionHandler {

@ExceptionHandler(value =Exception.class)

public String exceptionHandler(Exception e){

System.out.println(“未知異常!原因是:”+e);

return e.getMessage();

}

}

上述的示例中,我們對捕獲的異常進行簡單的二次處理,返回異常的信息,雖然這種能夠讓我們知道異常的原因,但是在很多的情況下來說,可能還是不夠人性化,不符合我們的要求。那么我們這里可以通過自定義的異常類以及枚舉類來實現(xiàn)我們想要的那種數(shù)據(jù)吧。

自定義基礎(chǔ)接口

首先定義一個基礎(chǔ)的接口類,自定義的錯誤描述枚舉類需實現(xiàn)該接口。代碼如下:

public interface BaseErrorInfoInterface {

/** 錯誤碼*/

String getResultCode();

/** 錯誤描述*/

String getResultMsg();

}

自定義枚舉類

然后我們這里在自定義一個枚舉類,并實現(xiàn)該接口。代碼如下:

public enum CommonEnum implements BaseErrorInfoInterface {

// 數(shù)據(jù)操作錯誤定義

SUCCESS(“200”, “成功!”),

BODY_NOT_MATCH(“400”,“請求的數(shù)據(jù)格式不符!”),

SIGNATURE_NOT_MATCH(“401”,“請求的數(shù)字簽名不匹配!”),

NOT_FOUND(“404”, “未找到該資源!”),

INTERNAL_SERVER_ERROR(“500”, “服務(wù)器內(nèi)部錯誤!”),

SERVER_BUSY(“503”,“服務(wù)器正忙,請稍后再試!”)

;

/** 錯誤碼 */

private String resultCode;

/** 錯誤描述 */

private String resultMsg;

CommonEnum(String resultCode, String resultMsg) {

this.resultCode = resultCode;

this.resultMsg = resultMsg;

}

@Override

public String getResultCode() {

return resultCode;

}

@Override

public String getResultMsg() {

return resultMsg;

}

}

自定義異常類

然后我們在來自定義一個異常類,用于處理我們發(fā)生的業(yè)務(wù)異常。代碼如下:

public class BizException extends RuntimeException {

private static final long serialVersionUID = 1L;

/**

* 錯誤碼

*/

protected String errorCode;

/**

* 錯誤信息

*/

protected String errorMsg;

public BizException() {

super();

}

public BizException(BaseErrorInfoInterface errorInfoInterface) {

super(errorInfoInterface.getResultCode());

this.errorCode = errorInfoInterface.getResultCode();

this.errorMsg = errorInfoInterface.getResultMsg();

}

public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {

super(errorInfoInterface.getResultCode(), cause);

this.errorCode = errorInfoInterface.getResultCode();

this.errorMsg = errorInfoInterface.getResultMsg();

}

public BizException(String errorMsg) {

super(errorMsg);

this.errorMsg = errorMsg;

}

public BizException(String errorCode, String errorMsg) {

super(errorCode);

this.errorCode = errorCode;

this.errorMsg = errorMsg;

}

public BizException(String errorCode, String errorMsg, Throwable cause) {

super(errorCode, cause);

this.errorCode = errorCode;

this.errorMsg = errorMsg;

}

public String getErrorCode() {

return errorCode;

}

public void setErrorCode(String errorCode) {

this.errorCode = errorCode;

}

public String getErrorMsg() {

return errorMsg;

}

public void setErrorMsg(String errorMsg) {

this.errorMsg = errorMsg;

}

public String getMessage() {

return errorMsg;

}

@Override

public Throwable fillInStackTrace() {

return this;

}

}

自定義數(shù)據(jù)格式

順便這里我們定義一下數(shù)據(jù)的傳輸格式。代碼如下:

public class ResultBody {

/**

* 響應(yīng)代碼

*/

private String code;

/**

* 響應(yīng)消息

*/

private String message;

/**

* 響應(yīng)結(jié)果

*/

private Object result;

public ResultBody() {

}

public ResultBody(BaseErrorInfoInterface errorInfo) {

this.code = errorInfo.getResultCode();

this.message = errorInfo.getResultMsg();

}

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public Object getResult() {

return result;

}

public void setResult(Object result) {

this.result = result;

}

/**

* 成功

*

* @return

*/

public static ResultBody success() {

return success(null);

}

/**

* 成功

* @param data

* @return

*/

public static ResultBody success(Object data) {

ResultBody rb = new ResultBody();

rb.setCode(CommonEnum.SUCCESS.getResultCode());

rb.setMessage(CommonEnum.SUCCESS.getResultMsg());

rb.setResult(data);

return rb;

}

/**

* 失敗

*/

public static ResultBody error(BaseErrorInfoInterface errorInfo) {

ResultBody rb = new ResultBody();

rb.setCode(errorInfo.getResultCode());

rb.setMessage(errorInfo.getResultMsg());

rb.setResult(null);

return rb;

}

/**

* 失敗

*/

public static ResultBody error(String code, String message) {

ResultBody rb = new ResultBody();

rb.setCode(code);

rb.setMessage(message);

rb.setResult(null);

return rb;

}

/**

* 失敗

*/

public static ResultBody error( String message) {

ResultBody rb = new ResultBody();

rb.setCode(“-1”);

rb.setMessage(message);

rb.setResult(null);

return rb;

}

@Override

public String toString() {

return JSONObject.toJSONString(this);

}

}

自定義全局異常處理類

最后我們在來編寫一個自定義全局異常處理的類。代碼如下:

@ControllerAdvice

public class GlobalExceptionHandler {

private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

/**

* 處理自定義的業(yè)務(wù)異常

* @param req

* @param e

* @return

*/

@ExceptionHandler(value = BizException.class)

@ResponseBody

public ResultBody bizExceptionHandler(HttpServletRequest req, BizException e){

logger.error(“發(fā)生業(yè)務(wù)異常!原因是:{}”,e.getErrorMsg());

return ResultBody.error(e.getErrorCode(),e.getErrorMsg());

}

/**

* 處理空指針的異常

* @param req

* @param e

* @return

*/

@ExceptionHandler(value =NullPointerException.class)

@ResponseBody

public ResultBody exceptionHandler(HttpServletRequest req, NullPointerException e){

logger.error(“發(fā)生空指針異常!原因是:”,e);

return ResultBody.error(CommonEnum.BODY_NOT_MATCH);

}

/**

* 處理其他異常

* @param req

* @param e

* @return

*/

@ExceptionHandler(value =Exception.class)

@ResponseBody

public ResultBody exceptionHandler(HttpServletRequest req, Exception e){

logger.error(“未知異常!原因是:”,e);

return ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR);

}

}

因為這里我們只是用于做全局異常處理的功能實現(xiàn)以及測試,所以這里我們只需在添加一個實體類和一個控制層類即可。

實體類

又是萬能的用戶表 (^▽^)

代碼如下:

public class User implements Serializable{

private static final long serialVersionUID = 1L;

/** 編號 */

private int id;

/** 姓名 */

private String name;

/** 年齡 */

private int age;

public User(){

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String toString() {

return JSONObject.toJSONString(this);

}

}

Controller 控制層

控制層這邊也比較簡單,使用Restful風(fēng)格實現(xiàn)的CRUD功能,不同的是這里我故意弄出了一些異常,好讓這些異常被捕獲到然后處理。這些異常中,有自定義的異常拋出,也有空指針的異常拋出,當(dāng)然也有不可預(yù)知的異常拋出(這里我用類型轉(zhuǎn)換異常代替),那么我們在完成代碼編寫之后,看看這些異常是否能夠被捕獲處理成功吧!

代碼如下:

@RestController

@RequestMapping(value = “/api”)

public class UserRestController {

@PostMapping(“/user”)

public boolean insert(@RequestBody User user) {

System.out.println(“開始新增。。?!保?

//如果姓名為空就手動拋出一個自定義的異常!

if(user.getName()==null){

throw new BizException(“-1”,“用戶姓名不能為空!”);

}

return true;

}

@PutMapping(“/user”)

public boolean update(@RequestBody User user) {

System.out.println(“開始更新。。?!保?

//這里故意造成一個空指針的異常,并且不進行處理

String str=null;

str.equals(“111”);

return true;

}

@DeleteMapping(“/user”)

public boolean delete(@RequestBody User user) {

System.out.println(“開始刪除。。?!保?

//這里故意造成一個異常,并且不進行處理

Integer.parseInt(“abc123”);

return true;

}

@GetMapping(“/user”)

public List《User》 findByUser(User user) {

System.out.println(“開始查詢。。?!保?

List《User》 userList =new ArrayList《》();

User user2=new User();

user2.setId(1L);

user2.setName(“xuwujing”);

user2.setAge(18);

userList.add(user2);

return userList;

}

}

App 入口

和普通的SpringBoot項目基本一樣。

代碼如下:

@SpringBootApplication

public class App

{

public static void main( String[] args )

{

SpringApplication.run(App.class, args);

System.out.println(“程序正在運行。。?!保?

}

}

功能測試

我們成功啟動該程序之后,使用Postman工具來進行接口測試。

首先進行查詢,查看程序正常運行是否ok,使用GET 方式進行請求。

GET http://localhost:8181/api/user

”返回參數(shù)為:

{“id”:1,“name”:“xuwujing”,“age”:18}

”示例圖:

7922d7ee-c1d5-11eb-9e57-12bb97331649.png

可以看到程序正常返回,并沒有因自定義的全局異常而影響。

然后我們再來測試下自定義的異常是否能夠被正確的捕獲并處理。

使用POST方式進行請求

POST http://localhost:8181/api/user

”Body參數(shù)為:

{“id”:1,“age”:18}

”返回參數(shù)為:

{“code”:“-1”,“message”:“用戶姓名不能為空!”,“result”:null}

”示例圖:

796e0dd6-c1d5-11eb-9e57-12bb97331649.png

可以看出將我們拋出的異常進行數(shù)據(jù)封裝,然后將異常返回出來。

然后我們再來測試下空指針異常是否能夠被正確的捕獲并處理。在自定義全局異常中,我們除了定義空指針的異常處理,也定義最高級別之一的Exception異常,那么這里發(fā)生了空指針異常之后,它是回優(yōu)先使用哪一個呢?這里我們來測試下。

使用PUT方式進行請求。

PUT http://localhost:8181/api/user

”Body參數(shù)為:

{“id”:1,“age”:18}

”返回參數(shù)為:

{“code”:“400”,“message”:“請求的數(shù)據(jù)格式不符!”,“result”:null}

”示例圖:

79859b90-c1d5-11eb-9e57-12bb97331649.png

我們可以看到這里的的確是返回空指針的異常護理,可以得出全局異常處理優(yōu)先處理子類的異常。

那么我們在來試試未指定其異常的處理,看該異常是否能夠被捕獲。

使用DELETE方式進行請求。

DELETE http://localhost:8181/api/user

”Body參數(shù)為:

{“id”:1}

”返回參數(shù)為:

{“code”:“500”,“message”:“服務(wù)器內(nèi)部錯誤!”,“result”:null}

這里可以看到它使用了我們在自定義全局異常處理類中的Exception異常處理的方法。到這里,測試就結(jié)束了。順便再說一下,自義定全局異常處理除了可以處理上述的數(shù)據(jù)格式之外,也可以處理頁面的跳轉(zhuǎn),只需在新增的異常方法的返回處理上填寫該跳轉(zhuǎn)的路徑并不使用ResponseBody 注解即可。

細心的同學(xué)也許發(fā)現(xiàn)了在GlobalExceptionHandler類中使用的是ControllerAdvice注解,而非RestControllerAdvice注解,如果是用的RestControllerAdvice注解,它會將數(shù)據(jù)自動轉(zhuǎn)換成JSON格式,這種于Controller和RestController類似,所以我們在使用全局異常處理的之后可以進行靈活的選擇處理。

其它關(guān)于SpringBoot優(yōu)雅的全局異常處理的文章就講解到這里了,如有不妥,歡迎指正!

項目地址

SpringBoot全局異常的處理項目工程地址//github.com/xuwujing/springBoot-study/tree/master/springboot-exceptionHandler

編輯;jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4947

    瀏覽量

    73281
  • JDK
    JDK
    +關(guān)注

    關(guān)注

    0

    文章

    83

    瀏覽量

    17102
  • PUT
    PUT
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    6430
  • SpringBoot
    +關(guān)注

    關(guān)注

    0

    文章

    177

    瀏覽量

    638

原文標(biāo)題:看看人家SpringBoot的全局異常處理多么優(yōu)雅...

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    使用setjmp及l(fā)ongjmp函數(shù)處理異常

    使用setjmp和longjmp函數(shù):這是一種用于實現(xiàn)非局部跳轉(zhuǎn)的方法,就是在程序中設(shè)置一個跳轉(zhuǎn)點,并在某些情況下跳轉(zhuǎn)到該跳轉(zhuǎn)點,從而繞過中間的一些代碼或函數(shù)。這樣可以在某些情況下模擬異常處理的效果
    發(fā)表于 12-11 08:00

    檢查函數(shù)返回值的錯誤和異常處理方法

    檢查函數(shù)返回值:這是最常見也最基本的錯誤處理異常處理方法,就是在調(diào)用一個函數(shù)后,檢查其返回值是否符合預(yù)期或是否表示出錯或失敗。如果出錯或失敗,則根據(jù)返回值或者全局變量errno(定義
    發(fā)表于 12-11 06:48

    請問C語言開發(fā)單片機為什么大多數(shù)都采用全局變量的形式?

    C語言代碼,大多數(shù)都是使用全局變量,也就是用很多函數(shù)來操作這些變量,比如函數(shù)1把一個全局變量經(jīng)過一系列復(fù)雜的算法計算后改變了這個全局變量的值,然后函數(shù)2再拿著函數(shù)1處理過的這個
    發(fā)表于 12-04 07:47

    C++程序異常處理機制

    1、什么是異常處理? 有經(jīng)驗的朋友應(yīng)該知道,在正常的C和C++編程過程中難免會碰到程序不按照原本設(shè)計運行的情況。 最常見的有除法分母為零,數(shù)組越界,內(nèi)存分配失效、打開相應(yīng)文件失敗等等。 一個程序
    發(fā)表于 12-02 07:12

    如何使用SpringBoot、Vue2.0、MySQL開發(fā)一套云診所系統(tǒng)?

    SpringBoot是Java領(lǐng)域非常流行的快速開發(fā)框架,提供了豐富的生態(tài)和自動化配置,適合構(gòu)建微服務(wù)和單體應(yīng)用。 它可以很好地處理業(yè)務(wù)邏輯、數(shù)據(jù)持久化、安全性(Spring Security)和API接口
    的頭像 發(fā)表于 11-27 16:02 ?153次閱讀
    如何使用<b class='flag-5'>SpringBoot</b>、Vue2.0、MySQL開發(fā)一套云診所系統(tǒng)?

    線路保護光纖通道異常處理方法

    通道異常的 常見原因、處理步驟及預(yù)防措施 ,幫助運維人員快速定位問題,提升故障處理效率。 廣州郵科光纖線路保護系統(tǒng) 一、光纖通道異常的常見表現(xiàn) 當(dāng)線路保護光纖通道出現(xiàn)
    的頭像 發(fā)表于 11-17 10:01 ?495次閱讀
    線路保護光纖通道<b class='flag-5'>異常</b><b class='flag-5'>處理</b>方法

    醫(yī)院隨訪管理系統(tǒng)源碼,三級隨訪系統(tǒng)源碼,Java+Springboot,Vue,Ant-Design+MySQL5

    Java版隨訪系統(tǒng)源碼,醫(yī)院隨訪管理系統(tǒng)源碼,三級隨訪系統(tǒng)源碼,B/S前后端分離架構(gòu),自主版權(quán),落地案例。 技術(shù)框架:Java+Springboot,Vue,Ant-Design+MySQL5 開發(fā)
    的頭像 發(fā)表于 11-08 14:48 ?226次閱讀
    醫(yī)院隨訪管理系統(tǒng)源碼,三級隨訪系統(tǒng)源碼,Java+<b class='flag-5'>Springboot</b>,Vue,Ant-Design+MySQL5

    求助,關(guān)于全局中斷使能的問題求解

    各位朋友大家好,我最近在使用蜂鳥的板子進行開發(fā)時,遇到了這樣的問題:我的程序每次運行到使能全局中斷的時候,就像進入了死循環(huán)一樣,出不去了,如上圖,首先先打印“GI_EN begin!”這里是可以
    發(fā)表于 11-07 06:37

    如何處理電能質(zhì)量在線監(jiān)測裝置時鐘模塊自動同步異常的情況?

    處理電能質(zhì)量在線監(jiān)測裝置時鐘模塊自動同步異常,需遵循 “ 先定位異常類型→再分步驟排查(從軟到硬、從簡到繁)→最后驗證恢復(fù) ” 的邏輯,針對 PTP、GPS、NTP 三種主流同步方式的差異,采取
    的頭像 發(fā)表于 10-27 10:16 ?774次閱讀

    如何利用AI算法進行裝置數(shù)據(jù)的異常檢測?

    利用 AI 算法進行裝置數(shù)據(jù)異常檢測,需結(jié)合工業(yè)裝置的數(shù)據(jù)特性(如實時性、多源性、強時序性、噪聲干擾)和業(yè)務(wù)需求(如故障預(yù)警、安全合規(guī)、工藝優(yōu)化),通過 “數(shù)據(jù)預(yù)處理 - 算法選型 - 模型部署
    的頭像 發(fā)表于 09-05 15:27 ?1213次閱讀
    如何利用AI算法進行裝置數(shù)據(jù)的<b class='flag-5'>異常</b>檢測?

    碳化硅襯底 TTV 厚度測量數(shù)據(jù)異常的快速診斷與處理流程

    摘要 本文針對碳化硅襯底 TTV 厚度測量中出現(xiàn)的數(shù)據(jù)異常問題,系統(tǒng)分析異常類型與成因,構(gòu)建科學(xué)高效的快速診斷流程,并提出針對性處理方法,旨在提升數(shù)據(jù)異常
    的頭像 發(fā)表于 08-14 13:29 ?1009次閱讀
    碳化硅襯底 TTV 厚度測量數(shù)據(jù)<b class='flag-5'>異常</b>的快速診斷與<b class='flag-5'>處理</b>流程

    如何識別與處理振弦式鋼筋計異常數(shù)據(jù)?

    京峟思VWR型振弦式鋼筋計為例,解析異常數(shù)據(jù)的識別與處理方法,助您高效解決問題,同時展現(xiàn)其卓越性能!一、振弦式鋼筋計為何值得信賴?VWR型振弦式鋼筋計專為長期埋設(shè)
    的頭像 發(fā)表于 04-22 17:05 ?520次閱讀
    如何識別與<b class='flag-5'>處理</b>振弦式鋼筋計<b class='flag-5'>異常</b>數(shù)據(jù)?

    推薦!如何優(yōu)雅地擺好PCB絲???

    很多畫PCB的人,會認為絲印不影響電路的性能,所以,對絲印并不重視。但是,對于一個專業(yè)的硬件工程師來說,必須重視這些細節(jié)。 下面介紹如何優(yōu)雅地弄好PCB絲印。 1 擺放的位置 一般來說,電阻、電容
    發(fā)表于 04-08 14:59

    TJA1043的收發(fā)器,如果CAN總線出現(xiàn)異常,它會進入異常狀態(tài)嗎?

    關(guān)于 TJA1043 的收發(fā)器,如果 CAN 總線出現(xiàn)異常,它會進入異常狀態(tài)嗎?一旦處于異常狀態(tài),它的行為會如何?例如,可以發(fā)送數(shù)據(jù)包但無法接收,謝謝
    發(fā)表于 04-04 07:30

    串口通訊異常處理方法 串口設(shè)備連接方式

    串口通信異常處理方法 1. 異常檢測 在串口通信中,首先需要能夠檢測到異常情況。異常檢測可以通過以下幾種方式實現(xiàn): 硬件檢測 :利用串口硬件
    的頭像 發(fā)表于 12-27 09:53 ?5595次閱讀