Spring Boot 异常处理

全局异常处理

在 Spring 3.x 提出了 @ControllerAdvvice,可以与 @ExceptionHandler、@InitBinder、@ModelAttribute 等注解配套使用对程序异常进行处理。
异常的处理分为两类:局部异常处理全局异常处理

局部异常处理:@ExceptionHandler 和 @Controller 注解搭配使用,只有指定的Controller层出现了异常才会被@ExceptionHandler捕获到,但是实际开发中controller数量比较多,所以这种方式不是很适合。

全局异常处理:@ControllerAdvice搭配@ExceptionHandler用来解决全局异常。@RestControllerAdvice = @ControllerAdvice + @ResponseBody

Spring Boot 异常分类

Java中的异常有很多,按照 controller 进行分类,分为进入controller前的异常和业务层的异常。
在这里插入图片描述
进入controller之前的异常一般是 javax.servlet.ServletException 类型的异常,因此在全局异常处理的时候需要统一处理。几个常见异常如下:

  • NoHandlerFoundException:客户端的请求没有找到对应的controller,抛出404异常;
  • HttpRequestMethodNotSupportException:请求的http方法和controller允许的方法不一致;
  • MissingPathVariableException:未检测到路径参数;
  • MethodArgumentNotValidException:参数校验异常。

全局统一异常处理

  1. 建立返回状态枚举类 ResultCode
public enum ResultCode {

    SUCCESS(1000, "操作成功"),
    ERROR(2000, "操作失败"),
    ERROR_UNKNOW(2001, "未知失败"),
    ;

    private final Integer code;

    private final String msg;

    ResultCode(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}
  1. 建立返回数据封装类 JsonResult(部分)
@Data
public class JsonResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer code;

    private String msg;

    private T data;

    public static JsonResult success() {
        JsonResult<Object> result = new JsonResult<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setMsg(ResultCode.SUCCESS.getMsg());
        return result;
    }
    public static <T> JsonResult<T> success(T data) {
        JsonResult<T> result = new JsonResult<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setMsg(ResultCode.SUCCESS.getMsg());
        result.setData(data);
        return result;
    }

    public static JsonResult error() {
        JsonResult<Object> result = new JsonResult<>();
        result.setCode(ResultCode.ERROR.getCode());
        result.setMsg(ResultCode.ERROR.getMsg());
        return result;
    }

    public static JsonResult error(ResultCode resultCode) {
        JsonResult<Object> result = new JsonResult<>();
        result.code = resultCode.getCode();
        result.msg = resultCode.getMsg();
        return result;
    }
}
  1. 新建自定义异常 TipException,继承RuntimeException类
@Data
public class TipException extends RuntimeException {

    private ResultCode resultCode;

    public TipException(ResultCode resultCode) {
        this.resultCode = resultCode;
    }
}
  1. 全局异常处理类 GlobalExceptionHandler
@ControllerAdvice
public class GlobalExceptionHandle {

    // 指定捕获的异常
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public JsonResult tipExceptionHandle(HttpServletRequest request, Exception e, HttpServletResponse response) {
        TipException tipException = (TipException) e;
        JsonResult<Object> result = new JsonResult<>();
        return result.error(tipException.getResultCode());
    }
}
  1. 测试controller
@RestController
@RequestMapping("error")
public class ErrorController {

    @GetMapping("success")
    public JsonResult success() {
        return JsonResult.success();
    }

    @GetMapping("error")
    public JsonResult error(){
        return JsonResult.error();
    }

    @GetMapping("errorthrow")
    public JsonResult errorThrow() {
        if (true) {
        	// 抛出自定义异常,正常业务一般在service层抛出,这里仅作为测试demo
            throw new TipException(ResultCode.ERROR_UNKNOW);
        }
        return JsonResult.error();
    }
}

请求对应的地址后,返回的数据为封装的JsonResult对应的json格式数据。

{
	"code": 1000,
	"msg": "操作成功",
	"data": null
}
posted @ 2023-02-02 16:43  wangms821  阅读(83)  评论(0编辑  收藏  举报