简述
记录一些关于平时借助Spring MVC框架开发时,对异常处理的一些想法和总结。这里引用耗子叔的总结,将异常分为三大类:
- 资源的错误,例如没有打开文件权限,写文件出现错误,网络故障等。
- 程序的错误,比如空指针,非法参数的异常,这一类最好记录下来写入日志,并触发监控系统报警。
用户的错误,比如缺少参数,请求方式错误,这类错误通常由于用户错误操作导致的,对于这类错误我们需要做统计,有利于改善软件或者侦测是否有恶意请求,并反馈给用户修正。
对于我们能够预知并且需要告诉用户修正的错误,我们最好使用返回 码的形式; 对于我们不期望发生的事,我们可以使用异常捕捉。
代码
Java里常用try…catch…finally的形式来建立异常堆栈,但是这种做法的缺点是重复代码较多,每个需要处理的接口都需要加上如下这几行:
1 | try { |
Spring MVC提供了控制器增强来方便进行统一异常处理,首先可以自定义一个业务中的异常:
1 | /** |
这样我们可以在业务层检测到用户参数不合法,或者某些受检异常的时候,可以直接抛出该exception,接下来定义一个接口层VO或者叫DTO,用于异常产生时,返回特定格式的数据:
1 | /** |
当产生错误时,统一返回该数据传输对象,最后定义Spring MVC的控制器增强。我们的业务逻辑和控制逻辑通常都是分开的,在控制逻辑里进行自定义异常的处理:
1 | /** |
其中,@ControllerAdvice支持的限定范围有:
@ControllerAdvice(annotation=RestController.clcas)
,按注解;@ControllerAdvice("org.example.controllers")
,按包名;@ControllerAdvice(assignableTypes={ControllerInterface.class,AbstractController.class})
,按类型。
如果在Controller里某个方法直接使用@ExceptionHandler(RuntimeException.class)
注解,则表示该异常处理只针对于该Controller。