自定义异常模块

文章目录

1.模块创建

1.创建common-exception-starter模块
2.查看是否被父模块管理

2.具体实现

1.目录
2.pom.xml 引入依赖
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>common-exception</artifactId>

    <dependencies>
        <!-- common-tool -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-tool</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- 引入web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除logging,防止日志冲突 -->
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- log4j2日志 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
    </dependencies>
</project>
3.CustomException.java 自定义异常
java 复制代码
package com.sunxiansheng.exception;

import com.sunxiansheng.tool.response.RespBeanEnum;

/**
 * Description: 自定义异常类。
 *
 * @Author sun
 * @Create 2024/5/6 15:15
 * @Version 1.1
 */
public class CustomException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    /**
     * 异常状态码
     */
    private Integer errorCode;

    /**
     * 异常信息
     */
    private String errorMessage;


    public Integer getErrorCode() {
        return errorCode;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    /**
     * 重写getMessage方法,返回自定义的异常信息
     *
     * @return
     */
    @Override
    public String getMessage() {
        return this.errorMessage;
    }

    /**
     * 无参构造
     */
    public CustomException() {
    }


    /**
     * 通过错误码和错误信息构造异常
     *
     * @param errorCode
     * @param errorMessage
     */
    public CustomException(Integer errorCode, String errorMessage) {
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }

    /**
     * 通过枚举类构造异常
     *
     * @param respBeanEnum
     */
    public CustomException(RespBeanEnum respBeanEnum) {
        this.errorCode = respBeanEnum.getCode();
        this.errorMessage = respBeanEnum.getMessage();
    }
}
4.GlobalExceptionHandler.java 全局异常处理
java 复制代码
package com.sunxiansheng.exception;

import com.sunxiansheng.tool.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.validation.BindException;

import static com.sunxiansheng.tool.constant.HttpStatus.BAD_REQUEST;
import static com.sunxiansheng.tool.constant.HttpStatus.ERROR;

/**
 * 全局异常处理器
 *
 * @author sunxiansheng
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理 JSON 请求体参数校验失败JSR303 (MethodArgumentNotValidException)
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        String message = e.getAllErrors().get(0).getDefaultMessage();
        log.error("参数校验失败: {} | 异常详情: ", message, e);
        return Result.fail(BAD_REQUEST, message);
    }

    /**
     * 处理表单或查询参数校验失败 (BindException)
     */
    @ExceptionHandler(BindException.class)
    public Result<Object> handleBindException(BindException e) {
        String message = e.getAllErrors().get(0).getDefaultMessage();
        log.error("参数绑定失败: {} | 异常详情: ", message, e);
        return Result.fail(BAD_REQUEST, message);
    }

    /**
     * 处理自定义业务异常 (CustomException)
     */
    @ExceptionHandler(CustomException.class)
    public Result<Object> handleCustomException(CustomException e) {
        log.error("自定义异常: {} | 错误码: {} | 异常详情: ", e.getErrorMessage(), e.getErrorCode(), e);
        return Result.fail(e.getErrorCode(), e.getErrorMessage());
    }

    /**
     * 捕获所有未处理的系统异常
     */
    @ExceptionHandler(Exception.class)
    public Result<Object> handleException(Exception e) {
        log.error("系统异常: {} | 异常详情: ", e.getMessage(), e);
        return Result.fail(ERROR, "系统异常");
    }
}
5.ExceptionAutoConfiguration.java 自动配置类
java 复制代码
package com.sunxiansheng.exception.config;

import com.sunxiansheng.exception.GlobalExceptionHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Description: 异常自动配置类
 *
 * @Author sun
 * @Create 2024/10/28 15:37
 * @Version 1.0
 */
@Configuration
public class ExceptionAutoConfiguration {

    /**
     * 条件注入全局异常处理器
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public GlobalExceptionHandler globalExceptionHandler() {
        return new GlobalExceptionHandler();
    }
}
6.spring.factories 指定自动配置类
java 复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.sunxiansheng.exception.config.ExceptionAutoConfiguration
7.common-tool模块引入 HttpStatus.java
java 复制代码
package com.sunxiansheng.tool.constant;

/**
 * 返回状态码
 *
 * @author sunxiansheng
 */
public class HttpStatus {

    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功,但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;

    /**
     * 系统警告消息
     */
    public static final int WARN = 601;
}

3.测试

1.创建common-exception-starter-demo
2.目录
3.pom.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>common-exception-starter-demo</artifactId>

    <dependencies>
        <!-- common-exception -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-exception</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- common-web-starter -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-web-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- common-log4j2-starter -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-log4j2-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- common-validation-starter -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-validation-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
4.ExceptionController.java
java 复制代码
package com.sunxiansheng.exception.controller;

import com.sunxiansheng.exception.CustomException;
import lombok.Data;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * Description: 测试异常处理
 *
 * @Author sun
 * @Create 2024/10/28 17:41
 * @Version 1.0
 */
@RestController
public class ExceptionController {

    @Data
    static class User {
        @NotBlank(message = "用户名不能为空")
        private String name;
        @NotNull(message = "年龄不能为空")
        private Integer age;
    }

    /**
     * 测试异常
     *
     * @return
     */
    @RequestMapping("/testException")
    public String testException() {
        int i = 1 / 0;
        return "testException";
    }

    /**
     * 测试参数校验异常
     *
     * @param user
     * @return
     */
    @RequestMapping("/testMethodArgumentNotValidException")
    public String testMethodArgumentNotValidException(@RequestBody @Valid User user) {
        int i = 1 / 0;
        return "testException";
    }

    /**
     * 测试自定义异常
     *
     * @return
     */
    @RequestMapping("/testCustomException")
    public String testCustomException() {
        throw new CustomException(111, "自定义异常");
    }
}
5.ExceptionApplication.java
java 复制代码
package com.sunxiansheng.exception;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description: 异常处理启动类
 *
 * @Author sun
 * @Create 2024/10/28 17:32
 * @Version 1.0
 */
@SpringBootApplication
public class ExceptionApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExceptionApplication.class, args);
    }
}
6.测试结果
1.自定义异常
2.JSR303参数校验异常
3.其他异常
相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔3 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说8 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json