Spring MVC异常处理只响应实际抛出的异常对象,而非方法签名中throws声明的类型;需主动throw自定义异常并配合@ControllerAdvice+@ExceptionHandler或自定义HandlerExceptionResolver实现捕获。

在 Spring MVC 中,throws 关键字声明的异常本身不会自动“透传”给 HandlerExceptionResolver,真正起作用的是方法执行过程中**实际抛出的异常对象**,而不是签名中声明的 throws 类型。Spring 的异常处理机制只关心运行时抛出的异常,不解析方法签名里的 throws 声明。
throws 声明本身不影响异常处理流程
throws 是 Java 编译期检查机制(仅对受检异常强制要求),Spring 完全忽略它。Controller 方法写成:
public String handle() throws IOException, SQLException { ... }
只要方法体内没真抛出 IOException 或 SQLException,Spring 就完全感知不到这些类型。HandlerExceptionResolver 不会因为声明了就提前注册或拦截。
异常要被 HandlerExceptionResolver 捕获,必须实际抛出
只有当 Controller 方法执行中真的 throw 了一个异常实例,Spring 才会进入异常处理链,依次匹配:@ExceptionHandler、HandlerExceptionResolver 实现类(如 SimpleMappingExceptionResolver)、全局默认处理器。
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
- 抛出的异常类型必须与
HandlerExceptionResolver中配置的映射类型匹配(例如resolveException()方法参数类型可接收其父类) - 若使用
@ControllerAdvice + @ExceptionHandler,优先级高于普通HandlerExceptionResolver - 未被捕获的 RuntimeException 会直接向上冒泡,最终由 DispatcherServlet 调用
HandlerExceptionResolver
如何让自定义异常被正确解析
推荐做法是主动抛出自定义异常,并确保 HandlerExceptionResolver 能识别它:
- 定义业务异常类,继承
RuntimeException(避免强制throws) - 在 Controller 中
throw new BusinessException("xxx") - 实现
HandlerExceptionResolver,在resolveException()中判断exception instanceof BusinessException - 或用
@ControllerAdvice配合@ExceptionHandler(BusinessException.class)更简洁
受检异常需注意包装问题
如果 Controller 方法调用了声明 throws IOException 的底层方法,又不想在 Controller 层 try-catch,常见做法是:
- 用
RuntimeException包装后重新抛出:throw new RuntimeException(e); - Spring 默认的
HandlerExceptionResolver(如ResponseStatusExceptionResolver)通常只处理特定异常(如ResponseStatusException),对原始IOException不做响应 - 若坚持用受检异常,需自定义
HandlerExceptionResolver显式支持该类型,但不推荐
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










