Spring註解之@RestControllerAdvice

前言java

    前段時間部門搭建新系統,須要出異常後統一接口的返回格式,因而用到了Spring的註解@RestControllerAdvice。如今把此註解的用法總結一下。web

用法spring

    首先定義返回對象ResponseDtothis

 1 package com.staff.points.common;
 2 
 3 import lombok.Data;
 4 
 5 import java.io.Serializable;
 6 
 7 @Data
 8 public class ResponseDto<T> implements Serializable {
 9     private static final long serialVersionUID = -284719732991678911L;
10 
11     private String code;
12 
13     private String message;
14 
15     private T data;
16 
17     public static <T> ResponseDto<T> assemblingSuccessResponse(T data) {
18         ResponseDto<T> responseDto = new ResponseDto<>();
19         responseDto.setCode(ResponseCodeEnum.SUCCESS.getCode());
20         responseDto.setMessage(ResponseCodeEnum.SUCCESS.getMessage());
21         responseDto.setData(data);
22         return responseDto;
23     }
24 
25     public static <T> ResponseDto<T> assemblingSuccessResponse() {
26         ResponseDto<T> responseDto = new ResponseDto<>();
27         responseDto.setCode(ResponseCodeEnum.SUCCESS.getCode());
28         responseDto.setMessage(ResponseCodeEnum.SUCCESS.getMessage());
29         responseDto.setData(null);
30         return responseDto;
31     }
32 
33     public static <T> ResponseDto<T> assemblingFailureResponse(ResponseCodeEnum data) {
34         ResponseDto<T> responseDto = new ResponseDto<>();
35         responseDto.setCode(data.FAILURE.getCode());
36         responseDto.setMessage(data.FAILURE.getMessage());
37         return responseDto;
38     }
39 
40     public static <T> ResponseDto<T> assemblingFailureResponse() {
41         ResponseDto<T> responseDto = new ResponseDto<>();
42         responseDto.setCode(ResponseCodeEnum.FAILURE.getCode());
43         responseDto.setMessage(ResponseCodeEnum.FAILURE.getMessage());
44         return responseDto;
45     }
46 }

    而後定義返回碼的枚舉類,此處只定義了兩種,有須要能夠往下添加不少。spa

 1 package com.staff.points.common;
 2 
 3 import lombok.AllArgsConstructor;
 4 import lombok.Getter;
 5 
 6 @AllArgsConstructor
 7 @Getter
 8 public enum ResponseCodeEnum {
 9     SUCCESS("00", "成功"),
10     FAILURE("01", "系統異常");
11 
12 
13     private String code;
14     private String message;
15 }

    下面是自定義的異常類code

 1 package com.staff.points.common;
 2 
 3 import lombok.Data;
 4 
 5 @Data
 6 public class StaffPointsException extends RuntimeException{
 7     private String code;
 8     private String message;
 9     public StaffPointsException () {}
10 
11     public StaffPointsException (Exception e) {
12         super(e);
13     }
14 
15     public StaffPointsException (String code, String message) {
16         super(message);
17         this.code = code;
18         this.message = message;
19     }
20 
21     public StaffPointsException (ResponseCodeEnum codeEnum) {
22         super(codeEnum.getMessage());
23         this.code = codeEnum.getCode();
24         this.message = codeEnum.getMessage();
25     }
26 }

    而後是關鍵的@RestControllerAdvice修飾的類對象

 1 package com.staff.points.exception;
 2 
 3 import com.staff.points.common.ResponseCodeEnum;
 4 import com.staff.points.common.ResponseDto;
 5 import com.staff.points.common.StaffPointsException;
 6 import org.slf4j.Logger;
 7 import org.slf4j.LoggerFactory;
 8 import org.springframework.stereotype.Component;
 9 import org.springframework.web.bind.annotation.ExceptionHandler;
10 import org.springframework.web.bind.annotation.RestControllerAdvice;
11 
12 @RestControllerAdvice
13 @Component
14 public class UnifyExceptionHandler {
15     private Logger logger = LoggerFactory.getLogger(UnifyExceptionHandler.class);
16 
17     @ExceptionHandler(Exception.class)
18     public ResponseDto handlerCommonException (Exception e) {
19         ResponseDto responseDto = new ResponseDto<>();
20         responseDto.setCode(ResponseCodeEnum.FAILURE.getCode());
21         responseDto.setMessage(ResponseCodeEnum.FAILURE.getMessage());
22         logger.info("UnifyExceptionHandler.handlerCommonException exception:" + e);
23         return responseDto;
24     }
25     // 報StaffPointException時,對其進行攔截並處理的方法
26     @ExceptionHandler(StaffPointsException.class)
27     public ResponseDto handlerCustomizeException (StaffPointsException e) {
28         ResponseDto responseDto = new ResponseDto<>();
29         responseDto.setCode(e.getCode());
30         responseDto.setMessage(e.getMessage());
31         logger.info("UnifyExceptionHandler.handlerCustomizeException StaffPointsException:" + e);
32         return responseDto;
33     }
34 }

    運行代碼時,若是出現了StaffPointException,那麼就會被攔截進入第27行的方法(就是說能夠自由的在業務代碼裏往外throw自定義異常了);若是出現了其餘的異常,則進入18行的方法,統一返回。blog

驗證一下,在代碼裏造一個NPE異常時,返回結果:接口

1 {
2   "code": "01",
3   "message": "系統異常",
4   "data": null
5 }

    造一個StaffPointsException異常時,返回結果:get

1 {
2   "code": "99",
3   "message": "自定義業務異常",
4   "data": null
5 }

    它的做用原理,大致是先在spring初始化時將類掃描進容器,出異常後,在DispatcherServlet類的doDispatch方法中調用了對異常的攔截處理。

小結

    看@RestControllerAdvice源碼能夠知道,它就是@ControllerAdvice和@ResponseBody的合併。此註解經過對異常的攔截實現的統一異常返回處理,若是你們在項目中有相似的需求,不妨試一下,好用又方便。

相關文章
相關標籤/搜索