看看人家 SpringBoot 的全局異常處理多么優(yōu)雅_第1頁
看看人家 SpringBoot 的全局異常處理多么優(yōu)雅_第2頁
看看人家 SpringBoot 的全局異常處理多么優(yōu)雅_第3頁
看看人家 SpringBoot 的全局異常處理多么優(yōu)雅_第4頁
看看人家 SpringBoot 的全局異常處理多么優(yōu)雅_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

看看人家SpringBoot的全局異常處理,多么優(yōu)雅...本篇文章主要介紹的是SpringBoot項目進行全局異常的處理。SpringBoot全局異常準(zhǔn)備說明:如果想直接獲取工程那么可以直接跳到底部,通過鏈接下載工程代碼。開發(fā)準(zhǔn)備環(huán)境要求

JDK:1.8

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

<properties>

<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>

<java.version>1.8java.version>

<piler.source>1.8piler.source>

<piler.target>1.8piler.target>

properties>

<parent>

<groupId>org.springframework.bootgroupId>

<artifactId>spring-boot-starter-parentartifactId>

<version>1.5.17.RELEASEversion>

<relativePath

/>

parent>

<dependencies>

<dependency>

<groupId>org.springframework.bootgroupId>

<artifactId>spring-boot-starter-webartifactId>

dependency>

<dependency>

<groupId>org.springframework.bootgroupId>

<artifactId>spring-boot-starter-testartifactId>

<scope>testscope>

dependency>

<dependency>

<groupId>com.alibabagroupId>

<artifactId>fastjsonartifactId>

<version>1.2.41version>

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ù)的傳輸格式。代碼如下:搜索公眾號后端架構(gòu)師后臺回復(fù)“面試”,獲取一份驚喜禮包。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)

{

=

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

findByUser(User

user)

{

System.out.println("開始查詢...");

List

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工具來進行接口測試。搜索公眾號后端架構(gòu)師后臺回復(fù)“架構(gòu)整潔”,獲取一份驚喜禮包。首先進行查詢,查看程序正常運行是否ok,使用GET方式進行請求。GET

[http://localhost:8181/api/user](http://localhost:8181/api/user)返回參數(shù)為:{"id":1,"name":"xuwujing","age":18}示例圖:可以看到程序正常返回,并沒有因自定義的全局異常而影響。然后我們再來測試下

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論