spring boot项目09:全局异常处理-基础使用

JAVA 8

Spring Boot 2.5.3

---

访问Spring Web请求时,可能会出现一些异常(JDK或其它包定义 或 项目自定义的异常),此时,默认情况下,返回给 调用方的是默认信息,比如:

为了 统一响应信息格式  等需求,因此,需要对这些异常 做统一处理。

相关注解:

@ControllerAdvice + @ResponseBody 或 @RestControllerAdvice

@ExceptionHandler

注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice // 看这里
@ResponseBody
public @interface RestControllerAdvice {

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {

示例代码:

拦截 org.lib.mysqlhello 包(项目根包)下所有 Exception异常——范围很大。

/**
 * 统一异常处理
 * 使用切面时,如果处理了异常 并且 返回了值,则不会执行到这里
 * @author ben
 * @date 2021-08-22 13:02:34 CST
 */
@ControllerAdvice(value = {"org.lib.mysqlhello"})
@ResponseBody
// 同上面两个注解等效
//@RestControllerAdvice(value = {"org.lib.mysqlhello"})
@Slf4j
public class AppExceptionHandler {

	/**
	 * 注解 ResponseBody 是关键
	 * @author ben
	 * @date 2021-08-22 14:06:17 CST
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = {Exception.class})
	ResultVO<Object> handleException(Exception e) {
		log.error("发生异常: e={}, e.message={}", e.getClass(), e.getMessage());
		return ResultVO.getFailed(500, "发生异常-AppExceptionHandler", null);
	}
	
}

注:上面的 ResultVO类是 定义的 项目统一返回类;返回的 第三个参数为 null。

上面只有一个 @ExceptionHandler ,实际使用时 可以定义多个,用来拦截不同的 Exception。

存在多个时,还需要考虑到 它们的顺序。

测试结果:

官方文档 Spring Framework Documentation->Web Servlet 中会有详细介绍:

其中,对 @ExceptionHandler 方法的 入参、返回值 有做具体介绍:

使用期间的错误

一开始使用了 @ControllerAdvice,但 没有同时使用@ResponseBody,此时出现了错误——收不到@ExceptionHandler函数中定义的 返回值,此时返回 S.B.默认错误内容。

添加 @ResponseBody 后,问题得到解决——可以到 类上、也可以添加到 方法上,均可。

或者,使用 @RestControllerAdvice 替换两者。

参考文档

1、拦截机制中Aspect、ControllerAdvice、Interceptor、Fliter之间的区别详解

理解 这个顺序很重要。

2、springboot使用多个@RestControllerAdvice时的拦截顺序

3、SpringBoot 统一异常处理

4、

原文地址:https://www.cnblogs.com/luo630/p/15172444.html