Spring注解@RestControllerAdvice原理解析
這篇文章主要介紹了Spring注解@RestControllerAdvice原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
前言
前段時間部門搭建新系統(tǒng),需要出異常后統(tǒng)一接口的返回格式,于是用到了Spring的注解@RestControllerAdvice。現(xiàn)在把此注解的用法總結(jié)一下。
用法
首先定義返回對象ResponseDto
package com.staff.points.common; import lombok.Data; import java.io.Serializable; @Data public class ResponseDto<T> implements Serializable { private static final long serialVersionUID = -284719732991678911L; private String code; private String message; private T data; public static <T> ResponseDto<T> assemblingSuccessResponse(T data) { ResponseDto<T> responseDto = new ResponseDto<>(); responseDto.setCode(ResponseCodeEnum.SUCCESS.getCode()); responseDto.setMessage(ResponseCodeEnum.SUCCESS.getMessage()); responseDto.setData(data); return responseDto; } public static <T> ResponseDto<T> assemblingSuccessResponse() { ResponseDto<T> responseDto = new ResponseDto<>(); responseDto.setCode(ResponseCodeEnum.SUCCESS.getCode()); responseDto.setMessage(ResponseCodeEnum.SUCCESS.getMessage()); responseDto.setData(null); return responseDto; } public static <T> ResponseDto<T> assemblingFailureResponse(ResponseCodeEnum data) { ResponseDto<T> responseDto = new ResponseDto<>(); responseDto.setCode(data.FAILURE.getCode()); responseDto.setMessage(data.FAILURE.getMessage()); return responseDto; } public static <T> ResponseDto<T> assemblingFailureResponse() { ResponseDto<T> responseDto = new ResponseDto<>(); responseDto.setCode(ResponseCodeEnum.FAILURE.getCode()); responseDto.setMessage(ResponseCodeEnum.FAILURE.getMessage()); return responseDto; } }
然后定義返回碼的枚舉類,此處只定義了兩種,有需要可以往下添加很多。
package com.staff.points.common; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter public enum ResponseCodeEnum { SUCCESS("00", "成功"), FAILURE("01", "系統(tǒng)異常"); private String code; private String message; }
下面是自定義的異常類
package com.staff.points.common; import lombok.Data; @Data public class StaffPointsException extends RuntimeException{ private String code; private String message; public StaffPointsException () {} public StaffPointsException (Exception e) { super(e); } public StaffPointsException (String code, String message) { super(message); this.code = code; this.message = message; } public StaffPointsException (ResponseCodeEnum codeEnum) { super(codeEnum.getMessage()); this.code = codeEnum.getCode(); this.message = codeEnum.getMessage(); } }
然后是關(guān)鍵的@RestControllerAdvice修飾的類
package com.staff.points.exception; import com.staff.points.common.ResponseCodeEnum; import com.staff.points.common.ResponseDto; import com.staff.points.common.StaffPointsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice @Component public class UnifyExceptionHandler { private Logger logger = LoggerFactory.getLogger(UnifyExceptionHandler.class); @ExceptionHandler(Exception.class) public ResponseDto handlerCommonException (Exception e) { ResponseDto responseDto = new ResponseDto<>(); responseDto.setCode(ResponseCodeEnum.FAILURE.getCode()); responseDto.setMessage(ResponseCodeEnum.FAILURE.getMessage()); logger.info("UnifyExceptionHandler.handlerCommonException exception:" + e); return responseDto; } // 報StaffPointException時,對其進行攔截并處理的方法 @ExceptionHandler(StaffPointsException.class) public ResponseDto handlerCustomizeException (StaffPointsException e) { ResponseDto responseDto = new ResponseDto<>(); responseDto.setCode(e.getCode()); responseDto.setMessage(e.getMessage()); logger.info("UnifyExceptionHandler.handlerCustomizeException StaffPointsException:" + e); return responseDto; } }
運行代碼時,如果出現(xiàn)了StaffPointException,那么就會被攔截進入第27行的方法(就是說可以自由的在業(yè)務(wù)代碼里往外throw自定義異常了);如果出現(xiàn)了其他的異常,則進入18行的方法,統(tǒng)一返回。
驗證一下,在代碼里造一個NPE異常時,返回結(jié)果:
{ "code": "01", "message": "系統(tǒng)異常", "data": null }
造一個StaffPointsException異常時,返回結(jié)果:
{ "code": "99", "message": "自定義業(yè)務(wù)異常", "data": null }
它的作用原理,大體是先在spring初始化時將類掃描進容器,出異常后,在DispatcherServlet類的doDispatch方法中調(diào)用了對異常的攔截處理。
小結(jié)
看@RestControllerAdvice源碼可以知道,它就是@ControllerAdvice和@ResponseBody的合并。此注解通過對異常的攔截實現(xiàn)的統(tǒng)一異常返回處理,如果大家在項目中有類似的需求,不妨試一下,好用又方便。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
IntelliJ?IDEA?2022.2.3最新激活圖文教程(親測有用永久激活)
今天給大家分享一個?IDEA?2022.2.3?的激活破解教程,全文通過文字+圖片的方式講解,手把手教你如何激活破解?IDEA,?只需要幾分鐘即可搞定,對idea2022.2.3激活碼感興趣的朋友跟隨小編一起看看吧2022-11-11springboot2.0和springcloud Finchley版項目搭建(包含eureka,gateWay,F(xiàn)re
這篇文章主要介紹了springboot2.0和springcloud Finchley版項目搭建(包含eureka,gateWay,F(xiàn)reign,Hystrix),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05Spring Security+Spring Data Jpa如何進行安全管理
這篇文章主要介紹了Spring Security+Spring Data Jpa如何進行安全管理,幫助大家更好的理解和學(xué)習(xí)Spring Security框架,感興趣的朋友可以了解下2020-09-09