java web中应通过@controlleradvice+@exceptionhandler实现全局异常处理,避免业务代码中手动redirect/forward;filter中异常需单独兜底,service/controller内抛异常交由统一机制处理。

在Java Web应用中,catch块捕获异常后直接重定向到错误页面,关键不是“手动跳转”,而是**交由统一异常处理机制接管**,避免在业务代码里写重复的response.sendRedirect()或request.getRequestDispatcher().forward(),这样才真正“优雅”。
用@ControllerAdvice + @ExceptionHandler全局捕获
这是Spring MVC最推荐的方式。把所有控制器抛出的异常集中拦截,统一返回错误视图或JSON响应。
- 定义一个全局异常处理器类,加上@ControllerAdvice注解
- 为不同异常类型(如NullPointerException、CustomBizException)编写@ExceptionHandler方法
- 方法内返回String(逻辑视图名),Spring自动解析为对应JSP/Thymeleaf页面,例如"error/500"
- 可同时设置Model传递错误信息,比如model.addAttribute("message", ex.getMessage())
配置SimpleMappingExceptionResolver(传统Servlet方式)
适用于非Spring Boot或老项目,通过XML或Java Config注册异常映射规则。
- 声明SimpleMappingExceptionResolver Bean
- 用exceptionMappings属性指定:key是异常全限定名,value是视图名称(如"java.lang.Exception" → "error/general")
- 支持默认视图defaultErrorView,兜底所有未匹配的异常
- 注意:它只对DispatcherServlet抛出的异常生效,filter或listener中的异常需另处理
Filter中统一拦截并转发(绕过Spring上下文时)
当异常发生在Spring容器之外(如Servlet Filter、Listener),无法被@ControllerAdvice捕获,这时可在Filter末尾做兜底处理。
- 在doFilter()的catch块中调用request.getRequestDispatcher("/error.jsp").forward(request, response)
- 务必检查response.isCommitted(),已提交则不能再forward,否则抛IllegalStateException
- 建议只用于技术性兜底,业务异常仍应尽量抛到Spring MVC流程中处理
避免在Service或Controller里手动redirect/forward
这是常见反模式:在try-catch里写response.sendRedirect("/error.html"),会导致流程混乱、状态码错误、SEO不友好。
- HTTP重定向(302)会丢失原始请求上下文和异常堆栈,不利于排查
- forward虽保留请求,但混入业务代码破坏分层,且难以统一日志和监控
- 正确做法是throw新异常(如throw new RuntimeException("DB failed", e)),让上层统一处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











