深入理解Java Spring中的全局异常处理:以Reggie项目为例

在Java Spring开发中,异常处理是非常关键的一部分。优雅地处理异常不仅可以提升用户体验,还能帮助开发者快速定位问题。本文将通过Reggie项目中的一个实例,深入探讨如何在Spring中使用@ControllerAdvice@ExceptionHandler实现全局异常处理。

项目背景

Reggie是一个基于Spring框架的Web应用,它可能包含多个控制器(Controller)来处理不同的业务逻辑。在这些控制器中,我们可能会遇到各种异常,如数据库约束违规、自定义业务异常等。为了统一处理这些异常并返回给前端统一的错误格式,我们引入了全局异常处理的概念。

全局异常处理类

在Reggie项目中,我们有一个名为GlobalExceptionHandler的类,它使用了@ControllerAdvice注解。这个注解表明该类是一个增强类,它可以对Controller进行全局增强。具体来说,它可以用来处理全局的异常、绑定数据、处理返回结果等。

注解说明

  • @ControllerAdvice(annotations = {RestController.class, Controller.class}): 表示这个增强类会对所有标注了@RestController@Controller的类生效。
  • @ResponseBody: 表示该类中所有方法的返回值都会自动转换为JSON格式响应给前端。
  • @Slf4j: 是Lombok库提供的注解,用于自动生成日志对象,方便记录日志。

异常处理方法

GlobalExceptionHandler类中,我们定义了两个异常处理方法,分别处理SQLIntegrityConstraintViolationExceptionCustomException

  1. exceptionHandler(SQLIntegrityConstraintViolationException ex): 这个方法专门处理数据库完整性约束违反的异常,通常是由于插入了重复的数据导致的。方法内部首先记录异常信息到日志中,然后检查异常信息是否包含"Duplicate entry",如果包含,则提取出重复的数据项并返回给前端一个友好的错误信息;如果不包含,则返回一个"未知错误"的信息。
  2. exceptionHandler(CustomException ex): 这个方法用来处理自定义的业务异常。业务异常通常是在业务逻辑处理过程中发现的,比如数据验证失败等。这个方法同样会记录异常信息到日志中,并直接返回异常信息给前端。

返回结果封装

在上述两个方法中,我们都返回了一个R<String>类型的对象。这通常是一个自定义的响应结果类,用来封装返回给前端的数据。在这个例子中,R类可能包含了一个状态码、消息和数据等字段。通过这种方式,我们可以保证所有返回给前端的数据都有统一的格式,便于前端处理。

总结与扩展

通过GlobalExceptionHandler类,我们可以很方便地实现Spring应用中的全局异常处理。这种方式不仅减少了重复代码,还提高了代码的可维护性和可读性。在实际项目中,我们还可以根据需要对这个类进行扩展,比如添加更多的异常处理方法来处理不同类型的异常,或者在方法内部添加更复杂的逻辑来处理异常情况。

文件源码:

java 复制代码
package com.itheima.reggie.common;

import com.sun.org.glassfish.external.statistics.annotations.Reset;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常捕获
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 异常处理方法
     * @param ex
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());

        if(ex.getMessage().contains("Duplicate entry")){
            String[] split = ex.getMessage().split(" ");
             String msg=split[2]+"已存在";
             return R.error(msg);
        }
                return R.error("未知错误");
    }

    /**
     * 异常处理方法(删除分类)
     * @param ex
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex){
        log.error(ex.getMessage());

        return R.error(ex.getMessage());
    }
}
相关推荐
计算机毕设指导613 分钟前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
Gu Gu Study15 分钟前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
Chris _data18 分钟前
二叉树oj题解析
java·数据结构
牙牙70523 分钟前
Centos7安装Jenkins脚本一键部署
java·servlet·jenkins
paopaokaka_luck31 分钟前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
以后不吃煲仔饭43 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师44 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker1 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法