S-mall-ssm 统一异常处理机制:@ExceptionHandler 如何优雅地处理所有错误?
【免费下载链接】S-mall-ssm小小商城系统,JavaWEB项目,基于SSM,仿天猫页面,功能齐全,实现了自动处理关联查询的通用Mapper、抽象 BaseService 类、注解鉴权、参数注解校验等项目地址: https://gitcode.com/gh_mirrors/smal/S-mall-ssm
S-mall-ssm是一个仿天猫页面的 JavaWEB 商城项目,基于 SSM(Spring + Spring MVC + MyBatis)搭建,功能覆盖商品、购物车、订单、评论与后台管理等完整电商链路。本文将深入讲解 S-mall-ssm 统一异常处理机制:借助 Spring MVC 的 @ExceptionHandler 注解,这个商城系统只用了一个方法就优雅地兜住了所有未捕获异常,还配合自定义异常类实现了精准的业务报错。对正在学习 SSM 项目异常处理、想给商城项目加上全局错误页的开发者来说,这份机制拆解非常值得收藏。😊
为什么商城项目需要统一异常处理?
在真实的电商场景里,用户的操作路径很长:加购、下单、支付、评论,任何一步都可能出错。如果每个 Controller 都各自 try-catch,代码会变得又臭又长;如果放任异常不管,用户就会看到又丑又吓人的"白屏"或堆栈信息。
S-mall-ssm 的做法很聪明:把异常处理集中到一个基类里,所有 Controller 继承它,错误统一收口,页面统一呈现。这正是统一异常处理机制的核心价值——一处定义,全局生效。
认识 S-mall-ssm 的自定义异常类
先看 S-mall-ssm 在 exception 目录 下定义的两个业务异常:
- AuthException.java:权限类异常,例如"非法访问,没有权限"
- ParameterException.java:参数类异常,例如"手机号填写错误"
它们都是简单的Exception子类,通过构造函数接收提示消息。别小看这两个小类,它们是"精准报错"的关键:业务代码里想表达什么错误,就抛什么异常,语义一目了然。
核心揭秘:BaseController 里的 @ExceptionHandler
S-mall-ssm 统一异常处理的精华,集中在 BaseController.java 中,代码如下:
@ExceptionHandler public String handleException(HttpServletRequest request, Exception exception) { exception.printStackTrace(); return "500"; }这个方法的威力在于两点:
- @ExceptionHandler 注解:告诉 Spring MVC"此方法专门处理控制器抛出的异常",方法参数是
Exception,意味着它兜住所有类型的异常。 - 继承式全局生效:
AdminBaseController和FrontBaseController都继承自BaseController,而所有后台、前台控制器又分别继承这两个基类。于是整个项目的 Controller 全部被这张"异常安全网"覆盖,无需在任何一个业务方法里重复写 try-catch。
发生异常后,方法会打印堆栈便于排查,并统一返回名为500的视图,也就是错误页面 500.jsp。这个页面会展示exception.toString()的友好提示,用户看到的是整齐的警告框,而不是崩溃的白屏。
业务层如何"抛出"异常?看订单模块实战
光有兜底还不够,还得让业务代码主动、精准地抛出异常。在 OrderFrontController.java 里能看到两个典型用法:
- 参数校验:创建订单时用正则校验手机号,格式不对就
throw new ParameterException("手机号填写错误") - 权限校验:修改购物车、删除订单前检查归属,不是本人操作就
throw new AuthException("非法访问,没有权限")
抛出后,异常顺着调用链冒泡到控制器层,最终被BaseController的 @ExceptionHandler 方法统一捕获,跳转到 500 页面。整个链路:业务层抛异常 → Controller 冒泡 → 基类统一捕获 → 错误页友好呈现,异常处理机制就这样优雅地闭环了。
配套的鉴权与参数校验机制
S-mall-ssm 的异常处理不是孤立存在的,它与项目里的注解鉴权、注解参数校验深度配合:
- AuthInterceptor.java:拦截请求,校验用户登录与权限,未通过即抛出异常
- VerificationAspect.java:AOP 切面处理
@Auth、@Nullable等注解的参数校验,异常同样交给全局处理 - 业务请求则通过 msg.jsp 返回"OutOfStock""success"等业务状态消息,属于可预期流程的控制流
这样一来,不可预期的系统异常走 @ExceptionHandler,可预期的业务结果走消息页,两类错误各得其所,职责非常清晰。
从 S-mall-ssm 学到的统一异常处理最佳实践
看完整个机制,可以提炼出适合自己项目复用的 4 个要点:
- 基类集中处理:把 @ExceptionHandler 放在 Controller 基类里,通过继承实现全局覆盖,比在每个类里粘贴代码优雅得多。
- 自定义异常分类:按权限、参数等维度定义语义化异常类,让"抛什么错"变得可读、可维护。
- 兜底 + 细化结合:一个
Exception级别的兜底方法保证永不白屏,同时用自定义异常保留精确信息。 - 业务消息与系统错误分离:可预期的结果(如库存不足)走业务消息页,真正的异常才进统一错误页,避免误用异常控制正常流程。
小结
S-mall-ssm 用约 20 行代码,就把整个商城的异常处理安排得明明白白:两个自定义异常类表达业务语义,一个 @ExceptionHandler 方法兜住全局,一张 500 页面保护用户体验。这套 SSM 项目统一异常处理方案,既适合新手理解 Spring MVC 异常处理的精髓,也适合开发者直接借鉴到自己的电商项目里。下次你的项目再出现莫名的 500,不妨先建一个 BaseController,把异常优雅地"接住"。🚀
【免费下载链接】S-mall-ssm小小商城系统,JavaWEB项目,基于SSM,仿天猫页面,功能齐全,实现了自动处理关联查询的通用Mapper、抽象 BaseService 类、注解鉴权、参数注解校验等项目地址: https://gitcode.com/gh_mirrors/smal/S-mall-ssm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考