定了个Plan,时间到了只完成了P,因为lan。
序言
有时候我们写代码是无法预测程序会出现什么异常的,也无法预知用户的神奇操作,因此,有时候我们的程序可能会爆出,500啊,404啊,401啊,403啊等等各种错误,这样错误让用户看到肯定很不好,我们只想给他们看到,类似 “网络错误!请稍后重试
”“服务器繁忙,请等会再来
”这样的话。
但是我们又不能每段程序都给你来上一段try-catch
所以,就需要一个手段,能让程序发生了异常之后,有一个统一的处理地方。
相关代码放在这里:https://gitee.com/siumu/blog_code.git
正文
接下来我们就学习一下springboot是怎么进行统一异常处理的。其实非常简单,就是两个注解而已。
首先我们先创建一个简单的springboot项目并写一个简单的统一异常处理类
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResultJSON handlerException(Exception e){
System.out.println("全局异常处理!----》》》》"+e.getMessage());
return new ResultJSON(500,"error");
}
}
没错,就是这么简单,我们就完成了一个全局异常处理,不管哪里发生了异常,都会在这里处理。我们先测试一下,先写一个请求接口:
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("login")
public ResultJSON login(){
int index = 1/0;
return new ResultJSON(200,"success");
}
}
这样,我们就简单完成了一个请求,并手动写了个bug用来触发异常。接下来我们启动项目并请求这个接口。
我一般不用postman,都是用IDEA自带的restClient工具,在菜单栏里Tools>HTTP Client:
点击之后会出现如下图这个东西,我们一般一看就知道这东西怎么用:
请求我们已经写好了,如果这个接口正常我们会返回{code: 200,msg: success}
这样的返回值,但是由于我们主动写了一个bug,它肯定会触发异常,就会走那个全局异常处理的方法。我们发送请求,试试看:
可以看到,我们发送请求,返回了
{
"code": 500,
"msg": "error",
"result": null
}
并且,控制台打印了全局异常处理的日志。这就是统一异常处理来返回那些无法预知的系统错误。
模拟异常处理
异常处理,主要还是看自己公司的代码规范,我这里就随便瞎写了一种,模拟一下。
首先我们先定义个枚举来维护所有的异常情况。
public enum CommonException {
LOGIN_FAIL(102, "用户名或者密码有误!"),
AUTHORITY_Fail(403, "没有相关权限!!");
private int code;
private String msg;
CommonException(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
然后我们定义一个基础的异常,并将这个枚举作为这个异常类的属性:
@Data
public class BaseException extends RuntimeException {
//异常的枚举
private CommonException exceptionContent;
public BaseException(CommonException exceptionContent) {
this.exceptionContent = exceptionContent;
}
}
接下来我们在统一异常处理里,捕获这个异常,并返回枚举里的code和msg
@ExceptionHandler(BaseException.class)
public ResultJSON handlerBaseException(BaseException e) {
System.out.println("全局异常处理!----》》》》" + e.getExceptionContent());
CommonException content = e.getExceptionContent();
return new ResultJSON(content.getCode(), content.getMsg());
}
然后我们写几个请求接口,来触发这些异常。
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("login")
public ResultJSON login(@RequestBody User user) {
System.out.println(user.getUsername() + "::" + user.getPassword());
return new ResultJSON(200, "success");
}
@PostMapping("loginFail")
public ResultJSON loginFail(@RequestBody User user) {
//判断用户是否为空
if (user == null) {
throw new BaseException(CommonException.LOGIN_FAIL);
}else if (!"xiumu".equals(user.getUsername())) {
throw new BaseException(CommonException.LOGIN_FAIL);
}
return new ResultJSON(200, "success");
}
@PostMapping("noAuth")
public ResultJSON noAuth(@RequestBody User user) {
//判断用户是否为空
if (user == null) {
throw new BaseException(CommonException.LOGIN_FAIL);
} else if (!"xiumu".equals(user.getUsername())) {
throw new BaseException(CommonException.AUTHORITY_Fail);
}
return new ResultJSON(200, "success");
}
}
可以看到,我们判断一些条件之后,直接抛出我们定义的异常即可。
最后我们写两个请求,运行一下就知道了。
请求结果如下:
总结
异常的内容不仅可以用枚举来定义,也可以将code和msg放在BaseException类中,然后定义多个异常类继承这个BaseException类,在代码中遇到不同的情况就抛出不同的异常。使用方式有很多,只是代码规范不同而已。
相关代码放在这里:https://gitee.com/siumu/blog_code.git