众所周知,我们可以通过全局异常捕捉拦截异常并返回友好提示给展示端。我就一直在想,既然都能把异常拦截到,难道就不能顺带把详细的报错信息也返回了?跟控制台报错输出那样,哪个类哪个方法哪行报错,刚好最近有空就捣鼓了一下,没想到特别简单!
不多BB,直接上效果图:
报错信息一目了然!再也不用为了定位问题而烦恼了!!
实现过程也很简单!三步:
1、创建通用返回对象
/**
* 统一接口返回值
*
* @author zzf
*/
@Data
@ApiModel("统一接口返回对象")
public class ServiceResponse<T> implements Serializable {
@ApiModelProperty("数据")
private T data;
@ApiModelProperty("状态编号")
private int code;
@ApiModelProperty("消息内容")
private String message;
@JsonInclude(JsonInclude.Include.NON_NULL)//如果为null则不进行序列化
@ApiModelProperty("报错信息")
private String error;
//这里还差一个构造方法,下文会补充。
}
2、配置全局异常拦截
/**
* 全局异常处理类
*
* @author zzf
*/
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//设置接口返回的http状态,根据需求设置
@ExceptionHandler(RuntimeException.class)
public ServiceResponse<?> handlerException(RuntimeException e) {
e.printStackTrace();
return new ServiceResponse<>(e);
}
}
3、处理异常并返回
敲黑板啦!!!全文重点~~
//这里就是上文所说的缺少的构造方法。
public ServiceResponse(RuntimeException e) {
this.setCode(ResponseCodeEnum.FAIL.getCode());
this.setMessage(ResponseCodeEnum.FAIL.getDesc());
//遍历并输出栈信息,具体的拼接逻辑可以根据需求写。
//类名可以截取,不用全路径,更加简洁明了。
StringBuilder buffer = new StringBuilder(e.getMessage()).append(":");
for (StackTraceElement element : e.getStackTrace()) {
String className = element.getClassName();
// 这里是筛选出自己的代码,其他jar包的堆栈信息就不需要返回了。
if (className.contains("com.copm")) {
buffer.append(className).append("(")
.append(element.getMethodName()).append(":")
.append(element.getLineNumber()).append(")。")
.append(System.lineSeparator());
}
}
this.setError(buffer.toString());
}
至此就可以实现如效果图那样的功能,是不是既简单又给力?如果本文对你有帮助,记得双击摸摸哒~