在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

關于SpringBoot如何優雅的全局異常處理

電子工程師 ? 來源:博客 ? 作者:虛無境 ? 2021-05-31 14:25 ? 次閱讀

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

開發準備

環境要求JDK:1.8SpringBoot:1.5.17.RELEASE

首先還是Maven的相關依賴:

《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》

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

代碼編寫

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

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

示例代碼:

@ControllerAdvice

public class MyExceptionHandler {

@ExceptionHandler(value =Exception.class)

public String exceptionHandler(Exception e){

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

return e.getMessage();

}

}

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

自定義基礎接口

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

public interface BaseErrorInfoInterface {

/** 錯誤碼*/

String getResultCode();

/** 錯誤描述*/

String getResultMsg();

}

自定義枚舉類

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

public enum CommonEnum implements BaseErrorInfoInterface {

// 數據操作錯誤定義

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

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

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

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

INTERNAL_SERVER_ERROR(“500”, “服務器內部錯誤!”),

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

;

/** 錯誤碼 */

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;

}

}

自定義異常類

然后我們在來自定義一個異常類,用于處理我們發生的業務異常。代碼如下:

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;

}

}

自定義數據格式

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

public class ResultBody {

/**

* 響應代碼

*/

private String code;

/**

* 響應消息

*/

private String message;

/**

* 響應結果

*/

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);

/**

* 處理自定義的業務異常

* @param req

* @param e

* @return

*/

@ExceptionHandler(value = BizException.class)

@ResponseBody

public ResultBody bizExceptionHandler(HttpServletRequest req, BizException e){

logger.error(“發生業務異常!原因是:{}”,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(“發生空指針異常!原因是:”,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);

}

}

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

實體類

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

代碼如下:

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風格實現的CRUD功能,不同的是這里我故意弄出了一些異常,好讓這些異常被捕獲到然后處理。這些異常中,有自定義的異常拋出,也有空指針的異常拋出,當然也有不可預知的異常拋出(這里我用類型轉換異常代替),那么我們在完成代碼編寫之后,看看這些異常是否能夠被捕獲處理成功吧!

代碼如下:

@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

”返回參數為:

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

”示例圖:

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

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

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

使用POST方式進行請求

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

”Body參數為:

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

”返回參數為:

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

”示例圖:

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

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

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

使用PUT方式進行請求。

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

”Body參數為:

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

”返回參數為:

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

”示例圖:

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

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

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

使用DELETE方式進行請求。

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

”Body參數為:

{“id”:1}

”返回參數為:

{“code”:“500”,“message”:“服務器內部錯誤!”,“result”:null}

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

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

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

項目地址

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

編輯;jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4882

    瀏覽量

    70057
  • JDK
    JDK
    +關注

    關注

    0

    文章

    82

    瀏覽量

    16782
  • PUT
    PUT
    +關注

    關注

    0

    文章

    5

    瀏覽量

    6354
  • SpringBoot
    +關注

    關注

    0

    文章

    175

    瀏覽量

    286

原文標題:看看人家SpringBoot的全局異常處理多么優雅...

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

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    如何識別與處理振弦式鋼筋計異常數據?

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

    推薦!如何優雅地擺好PCB絲印?

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

    TJA1043的收發器,如果CAN總線出現異常,它會進入異常狀態嗎?

    關于 TJA1043 的收發器,如果 CAN 總線出現異常,它會進入異常狀態嗎?一旦處于異常狀態,它的行為會如何?例如,可以發送數據包但無法接收,謝謝
    發表于 04-04 07:30

    如何用MES系統實現生產異常10分鐘快速響應

    在智能制造時代,生產異常響應速度直接影響交付周期與運營成本。研究表明,若能在異常發生后的10分鐘內介入處理,可避免80%以上的次生損失。珠海盈致通過MES系統構建的異常響應機制,正在重
    的頭像 發表于 03-18 16:37 ?255次閱讀

    串口通訊異常處理方法 串口設備連接方式

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

    socket編程中的錯誤處理技巧

    :錯誤處理能夠確保程序在遇到異常情況時不會崩潰,而是能夠優雅處理問題。 提升用戶體驗 :通過適當的錯誤處理,可以給用戶提供清晰的錯誤信息
    的頭像 發表于 11-01 17:47 ?1332次閱讀

    詳解MES系統的生產過程實時監控與異常處理

    萬界星空科技的MES系統能實時監控生產過程,檢測異常情況并自動糾正,確保生產過程的連續性和穩定性。通過可視化界面,管理人員可以實時查看生產進度和設備狀態。預警機制一旦檢測到異常情況,會立即觸發并通知相關人員。
    的頭像 發表于 10-28 15:57 ?539次閱讀
    詳解MES系統的生產過程實時監控與<b class='flag-5'>異常</b><b class='flag-5'>處理</b>

    電動機出現異常噪聲怎么處理

    當電動機發出異常噪聲時,首先需要檢查的是機械部件是否出現了問題。其中,軸承是最容易出現問題的部件之一。 軸承磨損或者損壞會導致電動機在運行過程中發出嗡嗡或者嘎吱嘎吱的聲音。這種聲音通常比較明顯,容易
    的頭像 發表于 09-14 17:19 ?785次閱讀

    ARM處理器的異常中斷響應過程

    ARM處理器的異常中斷響應是嵌入式系統設計中一個至關重要的環節,它確保了系統在面對內部或外部事件時能夠穩定、可靠地運行。
    的頭像 發表于 09-10 11:18 ?1580次閱讀

    TI C64x+ DSP內核異常處理機制的應用

    電子發燒友網站提供《TI C64x+ DSP內核異常處理機制的應用.pdf》資料免費下載
    發表于 08-28 11:54 ?0次下載
    TI C64x+ DSP內核<b class='flag-5'>異常</b><b class='flag-5'>處理</b>機制的應用

    Panasonic松下焊接電異常處理

    電子發燒友網站提供《Panasonic松下焊接電異常處理.pdf》資料免費下載
    發表于 08-19 14:24 ?0次下載

    嵌入式C編程常用的異常錯誤處理

    嵌入式C編程中,異常錯誤處理是確保系統穩定性和可靠性的重要部分。以下是一些常見的異常錯誤處理方法及其詳細說明和示例: 1. 斷言 (Assertions) 斷言用于在開發階段捕獲程
    發表于 08-06 14:32

    一站式統一返回值封裝、異常處理異常錯誤碼解決方案—最強的Sping Boot接口優雅響應處理

    1. 前言 統一返回值封裝、統一異常處理異常錯誤碼體系的意義在于提高代碼的可維護性和可讀性,使得代碼更加健壯和穩定。統一返回值封裝可以避免每一個接口都需要手工拼裝響應報文;統一異常
    的頭像 發表于 06-20 15:42 ?818次閱讀

    專業:出整套TP圖,抄板,調試,處理異常

    在觸摸屏行業工作多年,熟悉GF/GFF/GG結構與市場常用IC,手機/車載前裝后裝/工控/手表/商顯都做過 現承接所有關于觸摸屏項目評估,出圖以及觸摸屏調試,異常處理。歡迎各位同行聯系。 VX:yibai522
    發表于 05-30 12:01

    CYT2B7 SFlash被異常修改的原因?

    批次的; 比較奇怪的是,代碼中并沒有任何調用修改SFlash的API接口,僅有擦寫Code Flash和Work Flash代碼; 那有什么可能會導致芯片的SFlash區被異常修改呢?關于
    發表于 05-28 08:11
    主站蜘蛛池模板: 在线成人aa在线看片 | aa视频免费看 | 亚洲国产成人精品不卡青青草原 | 国产精品伦理一区二区三区 | 日本aaaaa| 免费看很黄很色裸乳视频 | 日韩一级在线观看 | 中文一区在线 | 国产小视频在线 | 成人综合网站 | 在线免费视频一区二区 | 视频在线观看高清免费看 | 亚洲精品色一区色二区色三区 | 国产小视频在线观看www | 午夜久久久 | 高清一级做a爱免费视 | 高清一级片 | 免费观看高清视频 | 国产激情久久久久影院小草 | 伊人久久网站 | 亚洲精品久久婷婷爱久久婷婷 | 黄色一级视频欧美 | 色吊丝中文字幕 | 5278欧美一区 | qvod高清在线成人观看 | 国产三级视频在线播放 | 看天堂 | 天天躁夜夜躁狠狠躁2021 | 亚洲97| 77788色淫网站女女免费视频 | 日本特黄特色视频 | 成人免费看黄页网址大全 | 久久午夜宅男免费网站 | 激情五月婷婷小说 | 综合色图 | 国产国语videosex另类 | 国模吧双双大尺度炮交gogo | 无人码一区二区三区视频 | 天天澡天天摸天天爽免费 | www.xxx.国产| 亚洲精品在线视频观看 |