Spring Boot @RestControllerAdvice全局异常处理最佳实践

本文主要是介绍Spring Boot @RestControllerAdvice全局异常处理最佳实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统...

前言

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

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

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

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

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

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

二、核心注解解析

1. @RestControllerAdvice

@RestControllerAdvice@ControChina编程llerAdvice@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.shjseep.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("; "));
  python  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 JSONjavascriptResult 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 {
    @Autowired
    private WebApplicationContext context;
    private MockMvc mockMvc;
    @BeforeEach
    void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }
    @Test
    void testBusinessException() throws Exception {
        mockMvc.perform(get("/api/test-exception"))
               .andExpect(status().isOk())
               .andExpect(jjavascriptsonPath("$.code").value("50000"));
    }
}

Q3:如何与FeignClient集成?

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

七、总结

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

  1. 提高代码可维护性

  2. 增强系统健壮性

  3. 改善用户体验

  4. 便于监控报警

到此这篇关于Spring Boot @RestControllerAdvice全局异常处理最佳实践的文章就介绍到这了,更多相关Spring Boot @RestControllerAdvice全局异常内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Spring Boot @RestControllerAdvice全局异常处理最佳实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155284

相关文章

Java堆转储文件之1.6G大文件处理完整指南

《Java堆转储文件之1.6G大文件处理完整指南》堆转储文件是优化、分析内存消耗的重要工具,:本文主要介绍Java堆转储文件之1.6G大文件处理的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言文件为什么这么大?如何处理这个文件?分析文件内容(推荐)删除文件(如果不需要)查看错误来源如何避

SpringBoot整合Dubbo+ZK注册失败的坑及解决

《SpringBoot整合Dubbo+ZK注册失败的坑及解决》使用Dubbo框架时,需在公共pom添加依赖,启动类加@EnableDubbo,实现类用@DubboService替代@Service,配... 目录1.先看下公共的pom(maven创建的pom工程)2.启动类上加@EnableDubbo3.实

SpringBoot整合(ES)ElasticSearch7.8实践

《SpringBoot整合(ES)ElasticSearch7.8实践》本文详细介绍了SpringBoot整合ElasticSearch7.8的教程,涵盖依赖添加、客户端初始化、索引创建与获取、批量插... 目录SpringBoot整合ElasticSearch7.8添加依赖初始化创建SpringBoot项

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs