springboot異常處理的基本規(guī)范
背景分析
在項(xiàng)目的開(kāi)發(fā)中,不管是對(duì)底層的數(shù)據(jù)邏輯操作過(guò)程,還是業(yè)務(wù)邏輯的處理過(guò)程,還是控制邏輯的處理過(guò)程,都不可避免會(huì)遇到各種可預(yù)知的、不可預(yù)知的異常。處理好異常對(duì)系統(tǒng)有很好的保護(hù)作用,同時(shí)會(huì)大大提高用戶(hù)的體驗(yàn)。
異常處理分析
概述
Java項(xiàng)目中處理異常方式無(wú)非兩種,要么執(zhí)行trycatch操作,要么執(zhí)行throw操作(拋給其它對(duì)象處理),無(wú)論采用哪種方式,其目的是讓我們的系統(tǒng)對(duì)異常要有反饋。但現(xiàn)在的問(wèn)題是我們?nèi)绾巫屵@種反饋代碼的編寫(xiě)即簡(jiǎn)單又直觀、友好。
處理規(guī)范
我們?cè)谔幚懋惓5倪^(guò)程中通常要遵循一定的設(shè)計(jì)規(guī)范,例如:
- 捕獲異常時(shí)與拋出的異常必須完全匹配,或者捕獲異常是拋出異常的父類(lèi)類(lèi)型。
- 避免直接拋出RuntimeException,更不允許拋出Exception或者Throwable,應(yīng)使用有業(yè)務(wù)含義的自定義異常(例如ServiceException)。
- 捕獲異常后必須進(jìn)行處理(例如記錄日志)。如果不想處理它,需要將異常拋給它的調(diào)用者。
- 最外層的邏輯必須處理異常,將其轉(zhuǎn)化成用戶(hù)可以理解的內(nèi)容。
- 避免出現(xiàn)重復(fù)的代碼(Don't Repeat Yourself),即DAY原則。
SpringBoot 工程下的異常處理
準(zhǔn)備工作
第一步:創(chuàng)建項(xiàng)目或module,并添加web依賴(lài),代碼如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
第二步:修改項(xiàng)目訪(fǎng)問(wèn)端口為80,例如
server.port=80
第三步:定義Controller類(lèi),代碼如下:
package com.cy.pj.arithmetic.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ArithmeticController {
@RequestMapping("doCompute/{n1}/{n2}")
@ResponseBody
public String doCompute(@PathVariable Integer n1,
@PathVariable Integer n2){
Integer result=n1/n2;
return "Result is "+result;
}
}
第四步啟動(dòng)項(xiàng)目進(jìn)行訪(fǎng)問(wèn)測(cè)試
在瀏覽器地址欄輸入http://localhost/doCompute/10/2,檢測(cè)輸出結(jié)果。
Result is 5
默認(rèn)異常處理
在瀏覽器地址欄輸入http://localhost/doCompute/10/0,檢測(cè)輸出結(jié)果。

對(duì)于這樣的默認(rèn)異常處理(spring boot提供),用戶(hù)體驗(yàn)不太友好,為了呈現(xiàn)更加友好的異常信息,我們通常要對(duì)異常進(jìn)行自定義處理。
自己try異常處理
在控制層方法中,我們可以進(jìn)行try catch處理,例如:
@RequestMapping("doCompute/{n1}/{n2}")
@ResponseBody
public String doCompute(@PathVariable Integer n1,
@PathVariable Integer n2){
try{
Integer result=n1/n2;
return "Result is "+result;
}catch(ArithmeticException e){
return "exception is "+e.getMessage();
}
}
一個(gè)Controller類(lèi)中通常會(huì)有多個(gè)方法,這樣多個(gè)方法中都寫(xiě)try語(yǔ)句進(jìn)行異常處理會(huì)帶來(lái)大量重復(fù)代碼的編寫(xiě),不易維護(hù)。
Controller內(nèi)部定義異常處理方法
在Controller類(lèi)中添加異常處理方法,代碼如下:
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public String doHandleArithmeticException(ArithmeticException e){
e.printStackTrace();
return "計(jì)算過(guò)程中出現(xiàn)了異常,異常信息為"+e.getMessage();
}
@ExceptionHandler注解描述的方法為異常處理方法(注解中的異常類(lèi)型為可處理的異常類(lèi)型),假如Controller類(lèi)中的邏輯方法中出現(xiàn)異常后沒(méi)有處理異常,則會(huì)查找Controller類(lèi)中有沒(méi)有定義異常處理方法,假如定義了,且可以處理拋出的異常類(lèi)型,則由異常處理方法處理異常。
控制層中的全局異常處理類(lèi)及方法定義
當(dāng)項(xiàng)目由多個(gè)控制層類(lèi)中有多個(gè)共性異常的處理方法定義時(shí),我們可以將這些方法提取到公共的父類(lèi)對(duì)象中,但是這種方式是一種強(qiáng)耦合的實(shí)現(xiàn),不利于代碼的維護(hù)。我們還可以借助spring框架中web模塊定義的全局異常處理規(guī)范進(jìn)行實(shí)現(xiàn),例如定義全局異常處理類(lèi),代碼如下:
package com.cy.pj.common.web;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ArithmeticException.class)
public String doHandleArithmeticException(ArithmeticException e){
e.printStackTrace();
return "計(jì)算過(guò)程中出現(xiàn)了異常,異常信息為"+e.getMessage();
}
}
其中,@RestControllerAdvice 注解描述的類(lèi)為全局異常處理類(lèi),當(dāng)控制層方法中的異常沒(méi)有自己捕獲,也沒(méi)有定義其內(nèi)部的異常處理方法,底層默認(rèn)會(huì)查找全局異常處理類(lèi),調(diào)用對(duì)應(yīng)的異常處理方法進(jìn)行異常處理。
總結(jié)
到此這篇關(guān)于springboot異常處理基本規(guī)范的文章就介紹到這了,更多相關(guān)springboot異常處理規(guī)范內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Day14基礎(chǔ)不牢地動(dòng)山搖-Java基礎(chǔ)
這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
java socket大數(shù)據(jù)傳輸丟失問(wèn)題及解決
這篇文章主要介紹了java socket大數(shù)據(jù)傳輸丟失問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java 交換兩個(gè)變量的數(shù)值實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇Java 交換兩個(gè)變量的數(shù)值實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
幾種JAVA細(xì)粒度鎖的實(shí)現(xiàn)方式
這篇文章主要為大家詳細(xì)介紹了幾種JAVA細(xì)粒度鎖的實(shí)現(xiàn)方式,感興趣的小伙伴們可以參考一下2016-05-05
Spring整合SpringMVC與Mybatis(SSM)實(shí)現(xiàn)完整登錄功能流程詳解
開(kāi)學(xué)學(xué)校開(kāi)始講servlet 后期要求做一個(gè)登錄功能,這個(gè)使用SSM先只做個(gè)簡(jiǎn)單的只帶登錄功能的,且項(xiàng)目使用了MyBatis-Plus來(lái)簡(jiǎn)化開(kāi)發(fā)流程??辞闆r決定要不要升級(jí)功能或者換個(gè)寫(xiě)法2022-09-09
SpringBoot整合POI導(dǎo)出通用Excel的方法示例
這篇文章主要介紹了SpringBoot整合POI導(dǎo)出通用Excel的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
關(guān)于TransmittableThreadLocal線(xiàn)程池中線(xiàn)程復(fù)用問(wèn)題的解決方案
這篇文章主要介紹了關(guān)于TransmittableThreadLocal線(xiàn)程池中線(xiàn)程復(fù)用問(wèn)題的解決方案,線(xiàn)程池復(fù)用線(xiàn)程,如果子線(xiàn)程執(zhí)行完未移除上下文,則會(huì)導(dǎo)致后續(xù)線(xiàn)程可以取到之前線(xiàn)程設(shè)置的屬性,需要的朋友可以參考下2023-11-11

