欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Spring Boot全局异常处理最佳实践:@RestControllerAdvice深度解析

Spring Boot全局异常处理最佳实践:@RestControllerAdvice深度解析

2025/5/19 1:11:11 来源:https://blog.csdn.net/2301_79437276/article/details/147966309  浏览:    关键词:Spring Boot全局异常处理最佳实践:@RestControllerAdvice深度解析

前言

在开发Spring Boot应用时,优雅地处理异常是保证系统健壮性和用户体验的关键。本文将详细介绍如何使用@RestControllerAdvice实现全局异常处理,并分享实际开发中的最佳实践。

一、为什么要使用全局异常处理?

  1. 代码复用:避免在每个Controller中重复编写try-catch

  2. 统一响应格式:标准化错误返回结构

  3. 异常分类处理:针对不同类型异常定制处理逻辑

  4. 减少样板代码:让业务逻辑更专注于核心流程

二、核心注解解析

1. @RestControllerAdvice

@RestControllerAdvice@ControllerAdvice@ResponseBody的组合注解,主要功能:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {// 可指定包路径或控制器类@AliasFor(annotation = ControllerAdvice.class)String[] value() default {};
}

2. @ExceptionHandler

用于标注处理特定异常的方法:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {// 指定要处理的异常类数组Class<? extends Throwable>[] value() default {};
}

三、实战代码实现

以下是完整全局异常处理器实现:

他会对于ExceptionHandler指定的异常进行处理,底层是通过AOP的技术实现的。

import com.sheep.shrine.result.JSONResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 全局异常处理器* @RestControllerAdvice = @ControllerAdvice + @ResponseBody*/
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 处理自定义业务异常*/@ExceptionHandler(GlobleException.class)public JSONResult handleBusinessException(GlobleException e) {e.printStackTrace();return JSONResult.error(e.getMessage());}/*** 处理所有未捕获异常*/@ExceptionHandler(Exception.class)public JSONResult handleSystemException(Exception e) {e.printStackTrace();return JSONResult.error("系统异常,正在殴打程序员...", "50000");}
}

四、进阶使用技巧

1. 异常分类处理

// 处理数据校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public JSONResult handleValidException(MethodArgumentNotValidException e) {String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining("; "));return JSONResult.error(message);
}// 处理数据库异常
@ExceptionHandler(DataAccessException.class)
public JSONResult handleDataAccessException(DataAccessException e) {log.error("数据库操作异常", e);return JSONResult.error("数据库服务异常");
}

2. 响应状态码控制

@ExceptionHandler(UnauthorizedException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public JSONResult handleUnauthorizedException(UnauthorizedException e) {return JSONResult.error("无权限访问", "403");
}

3. 日志记录优化

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public JSONResult handleException(Exception e) {log.error("系统异常: {}", e.getMessage(), e);return JSONResult.error("系统繁忙");}
}

五、最佳实践建议

  1. 异常分类细化:不要只用一个Exception.class处理所有异常

  2. 敏感信息过滤:生产环境不要返回堆栈信息

  3. 错误码规范:制定统一的错误码体系

  4. 日志完善:关键异常必须记录完整上下文

  5. 性能考虑:异常处理逻辑应尽量轻量

六、常见问题解答

Q1:全局异常处理器不生效怎么办?

  • 检查是否在Spring扫描路径下

  • 确认没有其他异常处理器覆盖

  • 检查是否有Filter提前处理了异常

Q2:如何测试全局异常处理器?

@SpringBootTest
class GlobalExceptionHandlerTest {@Autowiredprivate WebApplicationContext context;private MockMvc mockMvc;@BeforeEachvoid setup() {mockMvc = MockMvcBuilders.webAppContextSetup(context).build();}@Testvoid testBusinessException() throws Exception {mockMvc.perform(get("/api/test-exception")).andExpect(status().isOk()).andExpect(jsonPath("$.code").value("50000"));}
}

Q3:如何与FeignClient集成?

@Configuration
public class FeignConfig {@Beanpublic ErrorDecoder errorDecoder() {return (methodKey, response) -> {// 将Feign异常转换为自定义异常return new BusinessException("远程服务调用失败");};}
}

七、总结

通过@RestControllerAdvice实现全局异常处理可以:

  1. 提高代码可维护性

  2. 增强系统健壮性

  3. 改善用户体验

  4. 便于监控报警

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词