springboot学习之十二(异常处理统一返回)
SpringBoot的项目已经对有一定的异常处理了,但是对于我们开发者而言可能就不太合适了,因此我们需要对这些异常进行统一的捕获并处理。SpringBoot中有一个ControllerAdvice
的注解,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用ExceptionHandler
注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。
我们根据下面的这个示例来看该注解是如何使用吧。
示例代码:
@ControllerAdvice public class MyExceptionHandler { @ExceptionHandler(value =Exception.class) public String exceptionHandler(Exception e){ System.out.println("未知异常!原因是:"+e); return e.getMessage(); } }
上述的示例中,我们对捕获的异常进行简单的二次处理,返回异常的信息,虽然这种能够让我们知道异常的原因,但是在很多的情况下来说,可能还是不够人性化,不符合我们的要求。 那么我们这里可以通过自定义的异常类以及枚举类来实现我们想要的那种数据吧。
自定义枚举类
然后我们这里在自定义一个枚举类,并实现该接口。 代码如下:
public enum ReturnCode { SUCCESS(200, "操作成功"), NEED_LOGIN(401, "需要登录后操作"), NO_OPERATOR_AUTH(403, "无权限操作"), TOKEN_ILL(404,"token非法"), SYSTEM_ERROR(500, "出现错误"), USERNAME_EXIST(501, "用户名已经存在"), PHOMENUMBER_EXIST(502, "手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"), REQUEST_USERNAME(504, "必须填写用户名"), LOGIN_ERROR(505, "用户名或密码错误"); // 自定义状态码 private final int code; // 自定义描述 private final String msg; ReturnCode(int code, String errorMessage) { this.code = code; this.msg = errorMessage; } public int getCode() { return this.code; } public String getMsg() { return this.msg; } }
自定义数据返回结果
@Data public class ResultData<T> { /** * 响应编码 */ private Integer code; /** * 响应信息 */ private String msg; /** * 响应数据 */ private T data; /** * 接口请求时间 */ private long timestamp ; public ResultData(){ this.timestamp = System.currentTimeMillis(); } public ResultData(Integer code, String msg){ this.code=code; this.msg=msg; } public ResultData(Integer code, String msg, T data){ this.code=code; this.msg=msg; this.data=data; } public static ResultData success(){ return ResultData.success(ReturnCode.SUCCESS.getCode(),ReturnCode.SUCCESS.getMsg()); } public static ResultData success(int code, String msg){ ResultData<Object> resultData = new ResultData<>(); resultData.setCode(code); resultData.setMsg(msg); return resultData; } public static ResultData success(Object data){ ResultData<Object> resultData = new ResultData<>(ReturnCode.SUCCESS.getCode(),ReturnCode.SUCCESS.getMsg()); if (Objects.nonNull(data)){ resultData.setData(data); } return resultData; } public static ResultData error(int code, String msg){ ResultData<Object> resultData = new ResultData<>(code,msg); return resultData; } public static ResultData error(ReturnCode returnCode){ ResultData<Object> resultData = new ResultData<>(returnCode.getCode(), returnCode.getMsg()); return resultData; } }
自定义异常类
然后我们在来自定义一个异常类,用于处理我们发生的业务异常。 代码如下:
public class BizException extends RuntimeException { public BizException(String msg, Throwable cause) { super(msg, cause); } public BizException(String msg) { super(msg); } }
自定义全局异常处理类
最后我们在来编写一个自定义全局异常处理的类。 代码如下:
@RestControllerAdvice @Slf4j public class GlobalException { @ExceptionHandler(value = {ArrayIndexOutOfBoundsException.class}) public String arrayIndexOutOfBoundsException(Model model, Exception e){ model.addAttribute("msg",e.getMessage()); log.info(e.getMessage()); return "error"; } @ExceptionHandler(value = {NullPointerException.class}) public String nullPointerException(Model model,Exception e){ model.addAttribute("msg",e.getMessage()); log.info(e.getMessage()); return "error2"; } @ExceptionHandler(value = {ArithmeticException.class}) public ResultData<String> arithmeticException(Exception e){ log.info(e.getMessage()); return ResultData.error(ReturnCode.SYSTEM_ERROR.getCode(), e.getMessage()); } @ExceptionHandler(value = {BizException.class}) public ResultData<String> bizException(Exception e){ log.info(e.getMessage()); return ResultData.error(ReturnCode.SYSTEM_ERROR.getCode(), e.getMessage()); } @ExceptionHandler(value = {Exception.class}) public ResultData<String> exception(Exception e){ log.info(e.getMessage()); return ResultData.error(ReturnCode.SYSTEM_ERROR.getCode(), e.getMessage()); } }
下来就是测试了:
@RequestMapping("index03") public String index03(){ if(true){ throw new BizException("业务忙"); } return "index03"; } @GetMapping("/index05") public String index05(){ int i = 9/0; return "i"; }
(补充)404页面不存在异常捕获
在进行全局异常处理的时候,如果访问的url不存在,并不会被全局异常处理捕获到,所以还需要一个类来专门处理页面不存在即url错误的异常信息。
package com.test.exception; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class UrlNotFoundException implements ErrorController { @RequestMapping("/error") public R handle404Error() { // 处理自定义的url错误 404 错误逻辑 return new R(ExceptionEnum.URL_NOT_FOUND); } }
转:https://juejin.cn/post/6844903854752940045
https://blog.csdn.net/tianynnb/article/details/123847604
https://blog.csdn.net/weixin_34362991/article/details/91446455
https://www.cnblogs.com/ydteng/p/17542454.html