【快学springboot】5.全局异常捕获,异常流处理业务逻辑

栏目: Java · 发布时间: 4年前

内容简介:上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的。参数异常springboot默认的返回结构:不管是正常的情况,还是异常的情况,对于前端(或者app)来说,最好返回值的结构都是一致的,这样才方便解释。不管什么接口,都采用这样的数据结构返回给前端。比如约定code为0时是成功,其他错误定义出具体的错误码,message放错误信息,data对象放相应的数据。

上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的。参数异常springboot默认的返回结构:

{
 "timestamp": "2019-04-25T13:09:02.196+0000",
 "status": 400,
 "error": "Bad Request",
 "errors": [
 {
 "codes": [
 "Pattern.param.birthday",
 "Pattern.birthday",
 "Pattern.java.lang.String",
 "Pattern"
 ],
 "arguments": [
 {
 "codes": [
 "param.birthday",
 "birthday"
 ],
 "arguments": null,
 "defaultMessage": "birthday",
 "code": "birthday"
 },
 [],
 {
 "defaultMessage": "\d{4}-\d{2}-\d{2}",
 "codes": [
 "\d{4}-\d{2}-\d{2}"
 ],
 "arguments": null
 }
 ],
 "defaultMessage": "需要匹配正则表达式"\d{4}-\d{2}-\d{2}"",
 "objectName": "param",
 "field": "birthday",
 "rejectedValue": "apple",
 "bindingFailure": false,
 "code": "Pattern"
 }
 ],
 "message": "Validation failed for object='param'. Error count: 1",
 "path": "/validate/notblank"
}
复制代码

不管是正常的情况,还是异常的情况,对于前端(或者app)来说,最好返回值的结构都是一致的,这样才方便解释。

定义一个BaseResult类,定义返回值的数据结构

public class BaseResult {
 private int code;
 private String message;
 private Object data;
 // 省略getter setter方法,全参构造方法
}
复制代码

不管什么接口,都采用这样的数据结构返回给前端。比如约定code为0时是成功,其他错误定义出具体的错误码,message放错误信息,data对象放相应的数据。

定义全局异常处理器GlobalExceptionHandlerAdvice

@RestControllerAdvice
public class GlobalExceptionHandlerAdvice {

}
复制代码

使用RestControllerAdvice可以标识一个类为异常捕获类。

捕获异常

通过参数异常的测试,可以知道参数有异常时会抛出org.springframework.web.bind.MethodArgumentNotValidException。我们现在手动捕获 这个异常,并且返回一个BaseResult格式的响应。

@ExceptionHandler(MethodArgumentNotValidException.class)
public BaseResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
 BindingResult result = e.getBindingResult();
 FieldError fieldError = result.getFieldError();
 String defaultMessage = fieldError.getDefaultMessage();
 return new BaseResult(11000, defaultMessage, null);
}
复制代码

使用ExceptionHandler可以捕获异常类型。这里捕获了参数错误会抛出的异常,然后返回了自定义的结果。 这里错误码为随便填写,真实开发,建议定义一个错误码枚举类。

效果如下:

【快学springboot】5.全局异常捕获,异常流处理业务逻辑

返回的结果就比较友好了,前端处理起来也方便。

异常流处理业务逻辑

使用异常来处理业务逻辑,会使代码写起来更加流畅。比如说,一个删除用户数据的方法,返回值为void(无返回值),但是当传入的用户id不存在的时候,就应该返回一个用户不存在的结果,这对于void返回值的方法来说,显得无能为力。但是,使用异常流来处理该业务逻辑,会变得非常简单。我们直接抛出一个自定义异常,然后在异常捕获器上捕获该异常,再把结果返回给前端即可。

定义一个WebException

public class WebException extends RuntimeException {
 private int code;
 private String errorMsg;
 public WebException(int code, String errorMsg) {
 super(errorMsg);
 this.code = code;
 this.errorMsg = errorMsg;
 }
 @Override
 public synchronized Throwable fillInStackTrace() {
 return this;
 }
 // 省略getter setter方法
}
复制代码

这里定义了一个运行时异常,重写了fillInStackTrace方法,重写该方法是不保留异常信息栈。因为我们使用该异常来处理业务逻辑,都是我们手动抛出的,所以也不需要保存异常信息栈了,这会提升性能。

在异常捕获器添加WebException异常捕获

@ExceptionHandler(WebException.class)
public BaseResult handleWebException(WebException e) {
 return new BaseResult(e.getCode(), e.getErrorMsg(), null);
}
复制代码

模拟一段业务逻辑,抛出WebException

在之前的UserController类,修改之前写的deleteUser方法,如下:

@DeleteMapping(value = "/{userId}")
public Object deleteUser(@PathVariable(value = "userId") Integer userId) {
 if (userId == 0) {
 throw new WebException(-1, "用户不存在");
 }
 return new BaseResult(1, "成功", null);
}

复制代码

这里定义一个delete请求的接口,接收一个userId参数,如果userId等于0,则返回该用户不存在。测试结果如下:

当userId为0时,提示用户不存在

【快学springboot】5.全局异常捕获,异常流处理业务逻辑

当userId为1时,提示成功.

【快学springboot】5.全局异常捕获,异常流处理业务逻辑

总结

这里实现了全局异常捕获,并且介绍了异常流处理业务逻辑。这里只是一个小demo,还有很多待改进的地方。比如说,我没有定义一个错误码枚举类。在定义了错误码枚举类的前提下,修改构造BaseResult的模式,可以采用静态工厂模式来构造等。这里就不展开讨论了。


以上所述就是小编给大家介绍的《【快学springboot】5.全局异常捕获,异常流处理业务逻辑》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程卓越之道

编程卓越之道

Hyde R / 韩东海 / 电子工业出版社 / 2006-4-1 / 49.80

各位程序员一定希望自己编写的代码是能让老板赞赏、满意的代码;是能让客户乐意掏钱购买的代码;是能让使用者顺利使用的代码;是能让同行欣赏赞誉的代码;是能让自己引以为豪的卓越代码。本书作者为希望能编写出卓越代码的人提供了自己积累的关于卓越编程的真知灼见。它弥补了计算机科学和工程课程中被忽略的一个部分——底层细节,而这正是构建卓越代码的基石。具体内容包括:计算机数据表示法,二进制数学运算与位运算,内存组织......一起来看看 《编程卓越之道》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具