【spring boot】捕獲全局異常@RestControllerAdvice


 

 

一.由來

場景:  使用 Java的validation做入參的校驗  ,但是這種入參校驗在還沒有進入controller就會字段校驗不通過,從而直接返回異常信息給前端,

    前端的異常提醒, 類似於下面這種 很不友好的 

后端接口報錯提示信息:

 

 

 

 

 

 

 

 

二.解決方法

1.解決如上問題,需要對異常做捕獲處理,Spring boot 提供了@RestControllerAdvice 可以完成 全局異常捕獲處理

 

2.具體實現

 

 

2.1  定義請求入參GlobalParams

【比如,使用Java的validation做入參的校驗 這種場景】

package com.sxd.swapping.globalException.param; import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; /** * 使用 Java的validation做入參的校驗 * 測試一下全局異常怎么捕獲這種入參類型的校驗(因為此處入參校驗未通過,壓根就不會進Controller) */ @Data public class GlobalParams { @NotNull(message = "ID不能為空") private Long id; @NotEmpty(message = "集合不能為空") private List<String> myStrList; }
View Code

 

 

2.2 定義請求響應GlobalResult 

【可一定要getter/setter方法】

package com.sxd.swapping.globalException.result; import lombok.Data; /** * 自定義一個 統一響應體 */ @Data public class GlobalResult { public static final String SUCCESS_CODE = "0000"; public static final String ERROR_CODE = "9999"; /** * 狀態碼 */
    private String code; /** * 狀態碼描述 */
    private String message; /** * 響應結果 */
    private Object data; private GlobalResult(String code, String message) { this(code, message, null); } private GlobalResult(String code, String message, Object data) { this.code = code; this.message = message; this.data = data; } public static GlobalResult build(String code, String message) { return new GlobalResult(code, message); } public static GlobalResult build(String code, String message, Object data) { return new GlobalResult(code, message, data); } public static GlobalResult success() { return build(SUCCESS_CODE, "處理成功"); } public static GlobalResult success(String code, String message) { return build(code, message); } public static GlobalResult success(Object data) { return build(SUCCESS_CODE, "處理成功", data); } public static GlobalResult error() { return build(ERROR_CODE, "處理失敗"); } public static GlobalResult error(String message) { return error(ERROR_CODE, message); } public static GlobalResult error(String code, String message) { return build(code, message); } }
View Code

 

 

2.3 定義全局異常捕獲GlobalAdvice

【可捕獲一種特定異常,也可捕獲多種異常,依順序從上往下】

package com.sxd.swapping.globalException.advice; import com.sxd.swapping.globalException.result.GlobalResult; import org.apache.commons.collections4.CollectionUtils; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import java.util.List; /** * 全局異常捕獲 *@RestControllerAdvice都是對Controller進行增強的,可以全局捕獲spring mvc拋的異常。 * * ExceptionHandler 可以全局僅捕獲一種異常,也可以全局捕獲多種異常,從上到下 依次處理 * */ @RestControllerAdvice public class GlobalAdvice { /** * ExceptionHandler的作用是用來捕獲指定的異常 * 這里示例 捕獲 Java的validation做入參的校驗 的校驗失敗的異常 * 統一處理,免得返回前端 * @param e * @return
     */ @ExceptionHandler(MethodArgumentNotValidException.class) public GlobalResult handleStoreAuthException(MethodArgumentNotValidException e) { List<ObjectError> allErrors = e.getBindingResult().getAllErrors(); StringBuilder detailMsg = new StringBuilder(); if (CollectionUtils.isNotEmpty(allErrors)) { allErrors.stream().forEach(i -> detailMsg.append(i.getDefaultMessage()).append(";")); } return GlobalResult.build(GlobalResult.ERROR_CODE, detailMsg.toString()); } /** * ExceptionHandler的作用是用來捕獲指定的異常 * 這里示例 捕獲 Exception異常 * @param e * @return
     */ @ExceptionHandler(Exception.class) public GlobalResult handleStoreAuthException(Exception e) { return GlobalResult.build(GlobalResult.ERROR_CODE, e.getMessage()); } }
View Code

 

 

2.4 定義接口GlobalExceptionController

package com.sxd.swapping.globalException.controller; import com.sxd.swapping.globalException.param.GlobalParams; import com.sxd.swapping.globalException.result.GlobalResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @Slf4j @Controller @RequestMapping("/myglobal/exception") public class GlobalExceptionController { @ResponseBody @PostMapping(value = "/test") public GlobalResult myTest(@Valid @RequestBody GlobalParams params){ Long id = params.getId(); id = id / 0; log.info("業務處理!!!"); return GlobalResult.success(); } }
View Code

 

 

 

三.驗證結果

 

 

前端控件也可返回友好的異常提醒

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM