在项目中经常出现系统异常的情况,比如NullPointerException等等。如果默认未处理的情况下,springboot会响应默认的错误提示,这样对用户体验不是友好,系统层面的错误,用户不能感知到,即使为500的错误,可以给用户提示一个类似服务器开小差的友好提示等。这时候便可以使用全局异常处理器来优雅的处理全局异常
定义错误消息类
- 在全局异常类中会使用该错误消息进行初始化
- 注意该消息的toString方法要写成Json格式的
- 具体的错误消息初始化的时候也可以使用%s一类的占位符,后期调用静态方法,来填充多个参数
<code>@Data@AllArgsConstructor@Slf4jpublic class CodeMsg implements Serializable { private int code; private String msg; public static CodeMsg SUCCESS = new CodeMsg(200, "success"); public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务器错误"); public static CodeMsg INSERT_ERROR = new CodeMsg(500200, "插入错误"); public static CodeMsg UNKNOWN_ERROR = new CodeMsg(-999, "未知错误:%s"); //填充多个错误信息 public static CodeMsg BIND_ERROR = new CodeMsg(500300,"参数校验异常:%s"); public static CodeMsg UNSELECT_FILE_ERROR = new CodeMsg(500400,"未选择文件"); public static CodeMsg FILE_NOT_EXIST_ERROR = new CodeMsg(500500, "文件或文件夹不存在"); public static CodeMsg UPLOADING = new CodeMsg(500600, "正在上传"); //补充未知错误的具体信息 public CodeMsg fillArgs(Object... args){ int code = this.code; String message = String.format(this.msg,args); return new CodeMsg(code,message); } //处理异常时返回json的toString @Override public String toString() { return "CodeMsg{" + "code=" + code + ", msg='" + msg + '\\'' + '}'; } // public static void main(String[] args) { // log.info(new CodeMsg(0, "hello").toString()); // }}/<code>
定义全局异常类
<code>//继承RuntimeException,并定义serialVersionUIDpublic class GlobalException extends RuntimeException { private static final long serialVersionUID = -3586828184536704147L; private CodeMsg codeMsg; public GlobalException(CodeMsg codeMsg) { super(codeMsg.toString()); this.codeMsg = codeMsg; } public CodeMsg getCodeMsg() { return codeMsg; }}/<code>
定义返回结果类
<code>@Data@ApiModel(description = "返回结果")public class Resultimplements Serializable { private int code; private T data; private String msg; private Result(T data) { this.code = 0; this.msg = "success"; this.data = data; } private Result() { this.code = 0; this.msg = "success"; this.data = null; } private Result(CodeMsg codeMsg) { if (codeMsg == null) { return; } this.code = codeMsg.getCode(); this.msg = codeMsg.getMsg(); } public static /<code>Result success(T data) { return new Result (data); } public static Result success() { return new Result (); } public static Result error(CodeMsg codeMsg) { return new Result (codeMsg); }}
定义全局异常处理器
- 使用@ControllerAdvice来指定全局异常处理
- 使用@RestController返回json数据
- 使用@ExceptionHandler来捕获特定的异常种类
<code>@ControllerAdvice@RestController@Slf4jpublic class GlobalExceptionHandler { //自定义异常类 @ExceptionHandler(value = GlobalException.class) public Result<string> globalExceptionHandler(HttpServletRequest request, GlobalException e) { log.error(e.getCodeMsg().getMsg()); return Result.error(e.getCodeMsg()); } //参数检测不合格 @ExceptionHandler(value = MethodArgumentNotValidException.class) public Result<string> bindExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e) { log.error(e.getClass().toString()); // log.error(e.toString()); List<objecterror> errors = e.getBindingResult().getAllErrors(); StringBuilder errorMsg = new StringBuilder(); //此处仅取第一个 // ObjectError objectError = errors.get(0); for (ObjectError error : errors) { errorMsg.append(error.getDefaultMessage()).append(" "); } // String errorMsg = objectError.getDefaultMessage(); //填充具体异常 return Result.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg.toString())); } //其他异常类 @ExceptionHandler(value = Exception.class) public Result<string> defaultExceptionHandler(HttpServletRequest request, Exception e) { log.error(e.getClass().toString()); log.error(e.toString()); e.printStackTrace(); return Result.error(CodeMsg.UNKNOWN_ERROR.fillArgs(e.getClass().toString())); } //可定义详细的其他异常类 // @ExceptionHandler(AuthenticationException.class) //此处为shiro未登录异常类 // @ResponseStatus(HttpStatus.UNAUTHORIZED) // public String unAuth(AuthenticationException e) { // log.error("用户未登陆:", e); // return "/login.html"; // }}/<string>/<objecterror>/<string>/<string>/<code>
效果
至此,便完成了自定义的全局异常处理方法,访问效果如下
<code> //成功 { code = 0; msg = "success"; data = 456; } //失败 { code = 500100; msg = "服务器错误"; data = null; }/<code>
以上内容都是我自己的一些感想,分享出来欢迎大家指正,顺便求一波关注,有需要的私信我哦
出处:https://juejin.im/post/5e54796af265da575d20dd5d
閱讀更多 即將禿頭的Java程序員 的文章