SpringBoot 实战 (十四) | 统一处理异常

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 如题,今天介绍 SpringBoot 是如何统一处理全局异常的。SpringBoot 中的全局异常处理主要起作用的两个注解是 @ControllerAdvice 和 @ExceptionHandler ,其中 @ControllerAdvice 是组件注解,添加了这个注解的类能够拦截 Controller 的请求,而 ExceptionHandler 注解可以设置全局处理控制里的异常类型来拦截要处理的异常。 比如:@ExceptionHandler(value = NullPointException.class) 。

准备工作


  • SpringBoot 2.1.3
  • IDEA
  • JDK 8


依赖配置


<dependencies>
        <!-- JPA 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mysql 连接类 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- lombok 依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 单元测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


配置文件


spring:
  # 数据库相关
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=true
    username: root
    password: 123456
  jpa:
    hibernate:
      ddl-auto: update   #ddl-auto:设为 create 表示每次都重新建表
    show-sql: true


返回的消息类


public class Message<T> implements Serializable {
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 返回信息
     */
    private String message;
    /**
     * 返回的数据类
     */
    private T data;
    /**
     * 时间
     */
    private Long time;
    // getter、setter 以及 构造方法略。。。
}


工具类


用于处理返回的数据以及信息类,代码注释很详细不说了。


public class MessageUtil {
    /**
     * 成功并返回数据实体类
     * @param o
     * @param <E>
     * @return
     */
    public static <E>Message<E> ok(E o){
        return new Message<>(200, "success", o, new Date().getTime());
    }
    /**
     * 成功,但无数据实体类返回
     * @return
     */
    public static <E>Message<E> ok(){
        return new Message<>(200, "success", null, new Date().getTime());
    }
    /**
     * 失败,有自定义异常返回
     * @param code
     * @param msg
     * @return
     */
    public static <E>Message<E> error(Integer code,String msg){
        return new Message<>(code, msg, null, new Date().getTime());
    }
}


自定义异常


通过继承 RuntimeException ,声明 code 用于定义不同类型的自定义异常。主要是用于异常拦截出获取 code 并将 code 设置到消息类中返回。


public class CustomException extends RuntimeException{
    /**
     * 状态码
     */
    private Integer code;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public CustomException(Integer code, String message){
        super(message);
        this.code = code;
    }
}


异常拦截类


通过加入 @RestControllerAdvice 来声明该类可拦截 Controller 请求,同时在 handle方法加入 @ExceptionHandler 并在该注解中指定要拦截的异常类。


@RestControllerAdvice // 控制器增强处理(返回 JSON 格式数据),添加了这个注解的类能被 classpath 扫描自动发现
public class ExceptionHandle {
    @ExceptionHandler(value = Exception.class) // 捕获 Controller 中抛出的指定类型的异常,也可以指定其他异常
    public <E>Message<E> handler(Exception exception){
        if (exception instanceof CustomException){
            CustomException customException = (CustomException) exception;
            return MessageUtil.error(customException.getCode(), customException.getMessage());
        } else {
            return MessageUtil.error(120, "异常信息:" + exception.getMessage());
        }
    }
}


这里只对自定义异常以及未知异常进行处理,如果你在某方法中明确知道可能会抛出某个异常,可以加多一个特定的处理。比如说你明确知道该方法可能抛出 NullPointException 可以追加 NullPointException 的处理:


if (exception instanceof CustomException){
     CustomException customException = (CustomException) exception;
     return MessageUtil.error(customException.getCode(), customException.getMessage());
} else if (exception instanceof NullPointException ){
     return MessageUtil.error(500, "空指针异常信!");
} else {
     return MessageUtil.error(120, "异常信息:" + exception.getMessage());
}


controller 层


@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentService studentService;
    @GetMapping("/{id}")
    public Message<Student> findStudentById(@PathVariable("id") Integer id){
        if (id < 0){
            //测试自定义错误
            throw new CustomException(110, "参数不能是负数!");
        } else if (id == 0){
            //硬编码,为了测试
            Integer i = 1/id;
            return null;
        } else {
            Student student = studentService.findStudentById(id);
            return MessageUtil.ok(student);
        }
    }
}


完整代码


https://github.com/turoDog/Demo/tree/master/springboot_exception_demo


如果觉得对你有帮助,请给个 Star 再走呗,非常感谢。


Postman 测试


访问 http://localhost:8080/student/5 测试正常返回数据结果。

640.png

访问 http://localhost:8080/student/0 测试未知异常的结果。

640.png

访问 http://localhost:8080/student/-11 测试自定义异常的结果。

640.png

后语


写完看了下表,已是凌晨一点。 如果本文对你哪怕有一丁点帮助,请帮忙点好看。你的好看是我坚持写作的动力。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
Dubbo Java 应用服务中间件
深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案
本文深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案。通过检查GraalVM版本兼容性、配置反射列表、使用代理类、检查配置文件、禁用不支持的功能、查看日志文件、使用GraalVM诊断工具和调整GraalVM配置等步骤,帮助开发者快速定位并解决问题,确保服务的正常运行。
19 1
|
19天前
|
自然语言处理 Java API
Spring Boot 接入大模型实战:通义千问赋能智能应用快速构建
【10月更文挑战第23天】在人工智能(AI)技术飞速发展的今天,大模型如通义千问(阿里云推出的生成式对话引擎)等已成为推动智能应用创新的重要力量。然而,对于许多开发者而言,如何高效、便捷地接入这些大模型并构建出功能丰富的智能应用仍是一个挑战。
77 6
|
1月前
|
Java API Spring
springBoot:注解&封装类&异常类&登录实现类 (八)
本文介绍了Spring Boot项目中的一些关键代码片段,包括使用`@PathVariable`绑定路径参数、创建封装类Result和异常处理类GlobalException、定义常量接口Constants、自定义异常ServiceException以及实现用户登录功能。通过这些代码,展示了如何构建RESTful API,处理请求参数,统一返回结果格式,以及全局异常处理等核心功能。
|
1月前
|
Java 关系型数据库 数据库连接
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第3天】Spring Boot项目中数据库连接问题可能源于配置错误或依赖缺失。YAML配置文件的格式不正确,如缩进错误,会导致解析失败;而数据库驱动不匹配、连接字符串或认证信息错误同样引发连接异常。解决方法包括检查并修正YAML格式,确认配置属性无误,以及添加正确的数据库驱动依赖。利用日志记录和异常信息分析可辅助问题排查。
152 10
|
1月前
|
Java 关系型数据库 MySQL
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第4天】本文分析了Spring Boot应用在连接数据库时可能遇到的问题及其解决方案。主要从四个方面探讨:配置文件格式错误、依赖缺失或版本不兼容、数据库服务问题、配置属性未正确注入。针对这些问题,提供了详细的检查方法和调试技巧,如检查YAML格式、验证依赖版本、确认数据库服务状态及用户权限,并通过日志和断点调试定位问题。
|
2月前
|
缓存 NoSQL Java
Springboot实战——黑马点评之秒杀优化
【9月更文挑战第27天】在黑马点评项目中,秒杀功能的优化对提升系统性能和用户体验至关重要。本文提出了多项Spring Boot项目的秒杀优化策略,包括数据库优化(如索引和分库分表)、缓存优化(如Redis缓存和缓存预热)、并发控制(如乐观锁、悲观锁和分布式锁)以及异步处理(如消息队列和异步任务执行)。这些策略能有效提高秒杀功能的性能和稳定性,为用户提供更佳体验。
138 6
|
3月前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
3月前
|
Java API UED
【实战秘籍】Spring Boot开发者的福音:掌握网络防抖动,告别无效请求,提升用户体验!
【8月更文挑战第29天】网络防抖动技术能有效处理频繁触发的事件或请求,避免资源浪费,提升系统响应速度与用户体验。本文介绍如何在Spring Boot中实现防抖动,并提供代码示例。通过使用ScheduledExecutorService,可轻松实现延迟执行功能,确保仅在用户停止输入后才触发操作,大幅减少服务器负载。此外,还可利用`@Async`注解简化异步处理逻辑。防抖动是优化应用性能的关键策略,有助于打造高效稳定的软件系统。
70 2
|
3月前
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
1000 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
3月前
|
JSON Java API
解码Spring Boot与JSON的完美融合:提升你的Web开发效率,实战技巧大公开!
【8月更文挑战第29天】Spring Boot作为Java开发的轻量级框架,通过`jackson`库提供了强大的JSON处理功能,简化了Web服务和数据交互的实现。本文通过代码示例介绍如何在Spring Boot中进行JSON序列化和反序列化操作,并展示了处理复杂JSON数据及创建RESTful API的方法,帮助开发者提高效率和应用性能。
135 0
下一篇
无影云桌面