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

Spring Boot 3全局异常处理器如何覆盖框架默认异常处理?

解决Spring Boot 3全局异常处理器无法处理端点前置异常的问题

你的问题核心在于:Spring Boot的ResponseEntityExceptionHandler父类已经内置了针对路径变量转换错误、接口路径不存在这类早期异常的默认处理逻辑,这些特定异常的处理优先级高于你写的通用Exception.class处理器,所以自定义逻辑没生效。要覆盖默认行为,需要重写父类对应的异常处理方法,再配合必要的配置。

步骤1:重写ResponseEntityExceptionHandler的特定异常处理方法

在你的GlobalExceptionHandler中,重写父类中处理目标异常的方法,覆盖默认响应逻辑:

  • handleTypeMismatch:处理路径变量/请求参数类型转换错误(比如long类型传了字符串)
  • handleNoHandlerFoundException:处理接口路径不存在的情况

示例代码:

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    // 处理通用异常
    @ExceptionHandler(Exception.class)
    protected ResponseEntity<Object> handleGlobalException(Exception ex) {
        log.error("全局异常捕获:", ex);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(ResponseDto.buildUnknownErrorResponse());
    }

    // 覆盖:处理路径变量/参数类型转换错误
    @Override
    protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex,
                                                       HttpHeaders headers,
                                                       HttpStatusCode status,
                                                       WebRequest request) {
        log.error("类型转换异常:", ex);
        String message = String.format("参数%s的值'%s'类型错误,预期类型为%s",
                ex.getPropertyName(), ex.getValue(), ex.getRequiredType().getSimpleName());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(ResponseDto.buildErrorResponse(message));
    }

    // 覆盖:处理接口路径不存在的异常
    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex,
                                                                   HttpHeaders headers,
                                                                   HttpStatusCode status,
                                                                   WebRequest request) {
        log.error("路径不存在异常:", ex);
        String message = String.format("请求路径%s不存在", ex.getRequestURL());
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(ResponseDto.buildErrorResponse(message));
    }
}

步骤2:开启路径不存在异常的抛出

Spring Boot默认不会主动抛出NoHandlerFoundException,需要在配置文件中开启相关设置(以application.yml为例):

spring:
  mvc:
    throw-exception-if-no-handler-found: true # 路径不存在时抛出异常
  web:
    resources:
      add-mappings: false # 禁止静态资源映射,避免干扰路径匹配判断

补充说明

  • ResponseEntityExceptionHandler中的方法专门处理MVC层的前置异常(比如参数解析、路径匹配阶段的异常),这类异常发生在控制器方法执行之前,必须通过重写父类方法才能覆盖默认响应。
  • 保持@Order(Ordered.HIGHEST_PRECEDENCE)确保你的处理器优先级最高,不会被其他异常处理器覆盖。
  • 自定义ResponseDto可根据业务需求封装字段,示例参考:
public class ResponseDto<T> {
    private int code;
    private String message;
    private T data;

    public static ResponseDto<Void> buildUnknownErrorResponse() {
        ResponseDto<Void> dto = new ResponseDto<>();
        dto.setCode(500);
        dto.setMessage("系统未知错误");
        return dto;
    }

    public static ResponseDto<Void> buildErrorResponse(String message) {
        ResponseDto<Void> dto = new ResponseDto<>();
        dto.setCode(400);
        dto.setMessage(message);
        return dto;
    }

    // getter、setter 省略
}

内容的提问来源于stack exchange,提问作者Martijn Hiemstra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 17:05:05