
背景
在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 需要考虑以下几个问题 :
推荐做法
通常会将事务配置在 Service 层, 当数据库操作失败时, 让 Service 层抛出运行时异常, 而不进行 try-catch 处理, Spring 事物管理器就会进行回滚. 为了事务回滚
但 Service 层抛出后. 在 Controller 层就需要 try-catch 去捕获异常, 否则会返回原生错误信息到客户端. 但是, 如果在 Controller 层的每个方法体里面都写一些模板化的 try-catch 的代码, 代码不但不美观, 也增加了维护的难度, 特别是还需要对 Service 层的不同异常进行不同处理的时候.
@ControllerAdvice 注解是 Spring 3.2 中新增的. 用于拦截全局的 Controller 的异常. 注意:该注解只能拦截 Controller 不能拦截 Interceptor 的异常.
全局异常处理的步骤
在 Github 上的代码地址:
github.com/SanJingYe88…
① 使用统一的返回值
在 Controller 层的返回值只有两种, 一种是 Result 作为非分页请求的返回值, 一种是 PageResult 作为分页请求的返回值.
② 全局异常错误
编写一个 CodeMsg 全局异常错误码实体类. 将错误码集中管理, 然后通过 Result.error(CodeMsg codeMsg) 这种方式调用, 将业务错误码直接传回前端. 并且错误码可以随意扩展.
③ 自定义异常类
④ 校验工具类
可以创建校验工具类来对常用的校验做统一抽取, 还可以进行 i18n 国际化显示消息. 这里是我们自己手动编写了校验工具类, 还可以使用 Guava 提供的 Preconditions 类.
⑤ 全局异常处理类
编写 GlobalExceptionHandler 全局异常处理类. 对业务层传输来的异常做判断, 通过 Result.error(ex.getCodeMsg()) 对不同类型的异常统一返回.