统一异常处理和返回信息类型
文章目录
前言
项目中我们会将响应封装成JSON返回,一般我们会将所有接口的数据格式统一, 使前端对数据的操作更一致、轻松。 一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容。
信息返回类模板
@Data
public class R {
@ApiModelProperty(value = "是否成功")
private Boolean success;
@ApiModelProperty(value = "返回码")
private Integer code;
@ApiModelProperty(value = "返回消息")
private String message;
@ApiModelProperty(value = "返回数据")
private Map<String, Object> data = new HashMap<String, Object>();
//把构造方法私有
private R() {}
//成功静态方法
public static R ok() {
R r = new R();
r.setSuccess(true);
r.setCode(ResultCode.SUCCESS);
r.setMessage("成功");
return r;
}
//失败静态方法
public static R error() {
R r = new R();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("失败");
return r;
}
public R success(Boolean success){
this.setSuccess(success);
return this;
}
public R message(String message){
this.setMessage(message);
return this;
}
public R code(Integer code){
this.setCode(code);
return this;
}
public R data(String key, Object value){
this.data.put(key, value);
return this;
}
public R data(Map<String, Object> map){
this.setData(map);
return this;
}
}
异常处理
项目中不可避免会有服务器报错的情况,如果不配置异常处理机制,就会默认返回tomcat或者nginx的5XX页面,对普通用户来说,不太友好,用户也不懂什么情况。这时候需要我们程序员设计返回一个友好简单的格式给前端。
统一异常处理
1、创建统一异常处理器
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public R error(Exception e){
e.printStackTrace();
return R.error().message("执行了全局异常处理。。");
}
}
2、测试
返回统一错误结果
处理特定异常
1、添加异常处理方法
GlobalExceptionHandler.java中添加
//特定异常
@ExceptionHandler(ArithmeticException.class)
@ResponseBody //为了返回数据
public R error(ArithmeticException e) {
e.printStackTrace();
return R.error().message("执行了ArithmeticException异常处理..");
}
2、测试
自定义异常
1、创建自定义异常类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class XinException extends RuntimeException{
private Integer code;//状态码
private String msg;//异常信息
}
2、业务中需要的位置抛出XinException
// 模拟异常
try {
int i = 10 / 0;
}catch (Exception e){
// 执行自定义异常
throw new XinException(20001,"执行了自定义异常");
}
3、添加异常处理方法
//自定义异常
@ExceptionHandler(XinException.class)
@ResponseBody //为了返回数据
public R error(XinException e) {
log.error(e.getMessage());
e.printStackTrace();
return R.error().code(e.getCode()).message(e.getMsg());
}
4、测试
ControllerAdvice
本质上是一个Component
,因此也会被当成组建扫描。我们来看一下此类的注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
这个类是为那些声明了(@ExceptionHandler、@InitBinder 或 @ModelAttribute注解修饰的)方法的类而提供的专业化的@Component , 以供多个 Controller类所共享。
说白了,就是aop思想的一种实现,你告诉我需要拦截规则,我帮你把他们拦下来,具体你想做更细致的拦截筛选和拦截之后的处理,你自己通过@ExceptionHandler、@InitBinder 或 @ModelAttribute这三个注解以及被其注解的方法来自定义。
注意:需要在主类添加@ServletComponentScan注解