自定义异常体系在我们的日常开发中非常重要。一方面为了让用户体验更好,应该在发生异常的时候,在前端页面显示出错误信息。而另一方面,应该隐藏后端的异常,因为后端出现的异常对于前端开发者和用户来说毫无意义。所以,我们需要定义一种统一返回给前端的异常格式。
我们先明确两个概念:未知异常,已知异常
在开发过程中,我们有时会手动抛出一个异常,举个栗子:
1 | public String test(String id) { |
像这种参数为空抛出异常,这是我们程序员可以预知的异常,就称为已知异常。但是我们程序员不可能捕获所有的异常,而那些未捕获而在运行期间抛出的异常,我们就称为未知异常。
我们可以使用SpringBoot的全局异常处理。无论在程序中抛出什么异常,最终都会经过全局异常处理后才返回给前端。这样,我们就可以在全局异常处理中统一返回给前端的异常格式。
首先,我们先来定义统一返回信息类。这里的getter和setter方法非常重要。
1 | public class UnifyResponse { |
全局异常处理需要@ControllerAdvice和@ExceptionHandler:
1 |
|
介绍一下这里的两个方法:
1 | .class) (Exception |
这是处理”未知异常”的处理方法。方法的参数是Exception。因为未知异常我们是无法预知错误码的,这里我们定义为9999。同样,返回给前端的消息固定为”服务器内部错误“。因为返回的是一个对象,需要@ResponseBody注解。@HttpStatus返回HTTP的状态码。
1 | .class) (HttpException |
这是处理”已知异常“的处理方法。方法的参数是我们自定义的HttpException。由于message和httpStatus是动态决定的,所以返回的ResponseEntity,且不需要使用@ResponseBody。message和httpStatus的信息,我们要从自定义异常中获取。而没有使用@ResponseBody,我们需要在header中手动设置content-Type的值。
接下来介绍下自定义异常类:
1 | public class HttpException extends RuntimeException { |
1 | public class NotFoundException extends HttpException { |
自定义配置异常类:
1 | "ming") (value = |
@PropertySource关联了配置文件,而@ConfigurationProperties设置了配置文件中key的前缀,而成员变量codes对应者配置文件中的key值。
配置文件:
1 | 通用错误 = |
这里的前缀是不能少的,不然注入会失败。而且这里的字符串不需要加”“,否则返回前端的信息中也会带有引号。