You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot能否用单个@ExceptionHandler处理多个自定义异常?

问题

现有一段通过@ControllerAdvice实现的全局异常处理代码,功能正常但冗余严重。代码针对CustomException1、CustomException2、CustomException3分别编写了独立的@ExceptionHandler方法,逻辑高度相似,仅错误码和HttpStatus不同。所有自定义异常都继承自RuntimeException,希望用单个@ExceptionHandler统一处理这些自定义异常。

原异常处理器代码:

@ControllerAdvice
public class HandleExceptions {

    @ExceptionHandler(value = CustomException1.class)
    public ResponseEntity<Object> handleCustomException1(CustomException1 e) {
        HttpStatus status = HttpStatus.NOT_FOUND;
        DataResponse data = new DataResponse("custom status code for exception 1", e.getMessage());
        ExceptionResponse exceptionResponse = new ExceptionResponse(data);
        return new ResponseEntity<>(exceptionResponse, status);
    }
    
    @ExceptionHandler(value = CustomException2.class)
    public ResponseEntity<Object> handleCustomException2(CustomException2 e) {
        HttpStatus status = HttpStatus.NOT_FOUND;
        DataResponse data = new DataResponse("custom status code for exception 2", e.getMessage());
        ExceptionResponse exceptionResponse = new ExceptionResponse(data);
        return new ResponseEntity<>(exceptionResponse, status);
    }
    
    @ExceptionHandler(value = CustomException3.class)
    public ResponseEntity<Object> handleCustomException3(CustomException3 e) {
        HttpStatus status = HttpStatus.BAD_REQUEST;
        DataResponse data = new DataResponse("custom status code for exception 3", e.getMessage());
        ExceptionResponse exceptionResponse = new ExceptionResponse(data);
        return new ResponseEntity<>(exceptionResponse, status);
    }
}

相关实体类:

public class ExceptionResponse {
    private final DataResponse data;

    // 构造方法、Getter省略
}

public class DataResponse {
    private String statusCode;
    private String message;

    // 构造方法、Getter/Setter省略
}

原自定义异常基类:

public class CustomException extends RuntimeException{
    public CustomException(String message){         
        super(message);     
    }
}

期望响应示例:

{
  "data": {
    "statusCode": "1111",
    "message": "user not found"
  }
}
解决方案

核心思路是让每个自定义异常自身携带对应的错误码和HttpStatus属性,通过统一的基类处理器提取这些属性并生成响应。

1. 改造自定义异常基类

给基类添加错误码和Http状态的属性,通过构造方法注入:

import org.springframework.http.HttpStatus;

public class CustomException extends RuntimeException {
    private final String statusCode;
    private final HttpStatus httpStatus;

    public CustomException(String message, String statusCode, HttpStatus httpStatus) {
        super(message);
        this.statusCode = statusCode;
        this.httpStatus = httpStatus;
    }

    // Getter方法
    public String getStatusCode() {
        return statusCode;
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }
}

2. 定义具体自定义异常类

每个具体异常只需继承基类,在构造时传入专属的错误码和Http状态:

import org.springframework.http.HttpStatus;

public class CustomException1 extends CustomException {
    public CustomException1(String message) {
        super(message, "custom status code for exception 1", HttpStatus.NOT_FOUND);
    }
}

public class CustomException2 extends CustomException {
    public CustomException2(String message) {
        super(message, "custom status code for exception 2", HttpStatus.NOT_FOUND);
    }
}

public class CustomException3 extends CustomException {
    public CustomException3(String message) {
        super(message, "custom status code for exception 3", HttpStatus.BAD_REQUEST);
    }
}

3. 编写统一异常处理器

只用一个@ExceptionHandler处理基类CustomException,从异常实例中提取配置并构建响应:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class HandleExceptions {

    @ExceptionHandler(value = CustomException.class)
    public ResponseEntity<Object> handleCustomException(CustomException e) {
        DataResponse data = new DataResponse(e.getStatusCode(), e.getMessage());
        ExceptionResponse exceptionResponse = new ExceptionResponse(data);
        return new ResponseEntity<>(exceptionResponse, e.getHttpStatus());
    }
}

4. 验证效果

抛出任意具体自定义异常时,处理器会自动获取对应的错误码和Http状态,生成符合要求的响应。例如抛出CustomException1时,响应结构如下:

{
  "data": {
    "statusCode": "custom status code for exception 1",
    "message": "user not found"
  }
}

内容的提问来源于stack exchange,提问作者brain-dot-isEmpty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:52:52