【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