SpringBoot 杂记——使用 @ControllerAdvice 全局异常处理(七)

开门见山

目的是想要利用 @ControllerAdvice@ExceptionHandler 来全局捕获请求中的发生的异常,全局处理(响应)。大概的思路就是使用一个自定的异常类(包含我们需要的响应错误码、错误信息,具体看情况定义),然后请求业务中(请求处理方法、拦截器…)直接抛出异常就可以达到方便我们响应到客户端的目标。

@ControllerAdvice

通常配合 @ExceptionHandler@InitBinder@ModelAttribute 使用,适用于所有 @RequestMapping 注解的方法。

这里我们可以了解一下 @InitBinder 注解,是对入参做一系列的处理,如:时间格式的统一处理、设置不被允许的字段。

还是直奔今天的主题,使用 @ControllerAdvice@ExceptionHandler 来做全局异常处理。

@ExceptionHandler 的 value 属性可以传入一个数组,这里我们简单粗暴的捕获 Exception.class ,然后去根据捕获到的 exception 的具体类型给客户端响应不同的错误信息。

@ControllerAdvice
public class WebExceptionHandler {

	private Logger logger = LoggerFactory.getLogger(WebExceptionHandler.class);

	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public Rs errorHandler(HttpServletRequest req, HttpServletResponse res, Exception e) {
		logger.error("", e);
		if (e instanceof InvokeException) {
			InvokeException ex = (InvokeException)e;
			return Rs.err(ex.getErr(), ex.getMessage());
		}
		return Rs.errMsg("系统错误");
	}
}

这里为了更方便响应客户端,自定义了一个 InvokeException 继承自 RuntimeException,里面包含错误信息和错误码。

/**
 * 业务异常类,WebExceptionHandler 中会统一处理这个异常返回到接口
 */
public class InvokeException extends RuntimeException {

    private int err;

    public int getErr(){
        return err;
    }

    public InvokeException(String msg) {
        super(msg);
        this.err = Rs.ERROR_CODE_BIZ;
    }

    public InvokeException(int err, String msg) {
        super(msg);
        this.err = err;
    }

}

Use

在准备后异常捕获类和业务异常类之后,在业务代码中,当需要响应错误信息时,只需要抛异常就可以了。比如:业务中常常会做的数据校验、权限校验等。

	@GetMapping("/exception")
	Rs exception() {
		throw new InvokeException("丑拒!");
	}

访问 /exception, 响应:

{
    "err": -1001,
    "msg": "丑拒!",
    "data": {}
}

这里需要做一个说明的是:try...catch... 的异常不会进入异常捕获处理类中。

相关类:

  • WebExceptionHandler.java
  • InvokeException.java
  • Rs.java

GitHub

PlayWithSpringBoot

你可能感兴趣的:(JavaEE)