springboot,全局异常处理,AOP,对所有地方不单单是controller,捕获后事务回滚,但是保存异常发生记录

springboot,全局异常处理,AOP,对所有地方不单单是controller,捕获后事务回滚,但是保存异常发生记录

背景:
业务场景是对外接口调用失败,或者部分代码块执行失败,在系统中能统一记录下来。

方案

  1. 自定义异常
  2. 自定义注解
  3. 编写切面
    在切面中,将异常信息记录到表中。

1.自定义异常

public class OutApiException extends RuntimeException{
    private String exceptionType;
    private String exceptionInfo;
    private String exceptionParam;
    public OutApiException(String message) {
        super(message);
    }

    public OutApiException(String exceptionType,String exceptionInfo,String exceptionParam,String message) {
        super(message);
        this.exceptionType = exceptionType;
        this.exceptionInfo = exceptionInfo;
        this.exceptionParam = exceptionParam;
    }

    public String getExceptionType() {
        return exceptionType;
    }

    public void setExceptionType(String exceptionType) {
        this.exceptionType = exceptionType;
    }

    public String getExceptionInfo() {
        return exceptionInfo;
    }

    public void setExceptionInfo(String exceptionInfo) {
        this.exceptionInfo = exceptionInfo;
    }

    public String getExceptionParam() {
        return exceptionParam;
    }

    public void setExceptionParam(String exceptionParam) {
        this.exceptionParam = exceptionParam;
    }
}

2.自定义注解


import java.lang.annotation.*;

@Documented
@Target({ElementType.METHOD, ElementType.TYPE}) //可在类或者方法使用
@Retention(RetentionPolicy.RUNTIME)
public @interface OutApiServiceExceptionCatch {
}

3.切面编写

切面中那么多的代码,其实就是捕获对应注解下的,指定异常
其他的代码是我要存储到表中

为什么用jdbc?
因为我的项目用的mybatis,但是mybatis事务对运行时一行会全部回滚。
所有我单开了一个事务,这样其他的事务回滚了,但是异常可以正常存表。


import com.qygx.framework.exe.OutApiException;
import com.qygx.framework.exe.OutApiServiceExceptionCatch;
import com.qygx.mes.ding.domain.OaTask;
import com.qygx.mes.ding.mapper.OaTaskMapper;
import com.qygx.mes.ding.service.IOaTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import springfox.documentation.service.ResponseMessage;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

@Component
@Aspect
@Slf4j
public class ServiceExceptionHandler {
    @Autowired
    private IOaTaskService oaTaskService;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private DataSource dataSource;
    @Around("@annotation(com.qygx.framework.exe.OutApiServiceExceptionCatch)  || @within(com.qygx.framework.exe.OutApiServiceExceptionCatch)")
    public ResponseEntity<String> serviceExceptionHandler(ProceedingJoinPoint proceedingJoinPoint) {
        ResponseMessage returnMsg;
        try {
            returnMsg = (ResponseMessage) proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            log.error("ServiceExcepHandler serviceExcepHandler failed", throwable);
            //单独处理缺少参数异常
            if(throwable instanceof OutApiException) {
                Connection conn = null;
                try {
                    // 从数据源获取连接,并设置自动提交为false
                    conn = dataSource.getConnection();
                    conn.setAutoCommit(false);

                    String sql = "INSERT INTO test(oa_type, param) VALUES (?, ?)";
                    PreparedStatement pstmt = conn.prepareStatement(sql);
                    pstmt.setString(1, "value1");
                    pstmt.setString(2, "value2");
                    pstmt.executeUpdate();
                    conn.commit();
                } catch (Exception e) {
                    if (conn != null) {
                        try {
                            // 如果有异常发生,则回滚事务
                            conn.rollback();
                        } catch (SQLException ex) {
                            log.error("Failed to rollback transaction", ex);
                        }
                    }
                    throw new RuntimeException("Insert operation failed using JDBC", e);
                } finally {
                    if (conn != null) {
                        try {
                            // 关闭数据库连接
                            conn.close();
                        } catch (SQLException ex) {
                            log.error("Failed to close database connection", ex);
                        }
                    }
                }
                throw new RuntimeException();
            }else{
                throw new RuntimeException();
            }
        }
        throw new RuntimeException();
    }

}

4测试

添加注解,抛出指定异常

@Transactional
    @GetMapping("/test")
    public void testLogin() throws OutApiException {
        OaTask oaTask = new OaTask();
        oaTask.setParam("test0314");
        oaTaskService.insertOaTask(oaTask);
        throw new OutApiException("123");
    }

在这里插入图片描述
断点进到切面里面了
在这里插入图片描述
并且表中只保留了异常数据,;另一个事务回滚了

在这里插入图片描述

相关推荐

  1. SpringBoot全局异常捕获

    2024-03-17 01:42:04       34 阅读
  2. spring事务异常如何解决

    2024-03-17 01:42:04       23 阅读
  3. 异常处理:全局异常处理器

    2024-03-17 01:42:04       25 阅读
  4. SpringBoot全局异常处理

    2024-03-17 01:42:04       28 阅读
  5. Springboot全局异常处理

    2024-03-17 01:42:04       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-17 01:42:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-17 01:42:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-17 01:42:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-17 01:42:04       20 阅读

热门阅读

  1. Vue v-if 和 v-show的区别

    2024-03-17 01:42:04       21 阅读
  2. openssl3.2 - exp - generate ecc priv key

    2024-03-17 01:42:04       21 阅读
  3. PyTorch入门

    2024-03-17 01:42:04       20 阅读
  4. 指定元素懒加载

    2024-03-17 01:42:04       21 阅读
  5. 【爬虫介绍】了解爬虫的魅力

    2024-03-17 01:42:04       18 阅读
  6. linux下自定义显示文件拷贝进度

    2024-03-17 01:42:04       24 阅读
  7. 2024/3/26

    2024/3/26

    2024-03-17 01:42:04      19 阅读