项目地址:https://github.com/wenrongyao/springboot-demo.git
摘要:顶层异常处理,可以处理后台框架中没有处理到的异常,给前端友好的提示,也可以封装业务异常。
1、TopExceptionHandler 主要用的是@CotrollerAdivce,示例代码如下
/**
* 统一处理异常
* <p>
* Created by rongyaowen
* on 2018/12/17.
*/
@ControllerAdvice
public class TopExceptionHandler {
/**
* 最顶层的异常处理
*
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public String handleException(Exception e) {
LogUtil.info(e);
return GsonUtil.failJson("系统资源异常,不妨将您的操作告知管理员");
}
}
@ControllerAdvice:切面实现;
@ExceptionHandler:处理的异常种类,和catch一样,Exception是最顶层的异常;
@ResponseBody:表示返回body数据,不写表示返回页面
2、LogUtil日志工具的封装
这边处理的异常,一般都是我们在业务代码中没有处理到的,所有需要打印响应的日志以便后续定位bug。这个日志工具可以打印堆栈信息(参考网上资料)
/**
* 日志工具类
* <p>
* Created by rongyaowen
* on 2018/12/12.
*/
public class LogUtil {
public static Logger log = Logger.getLogger(LogUtil.class);
/**
* 打印信息
*
* @param obj
*/
public static void info(Object obj) {
try {
// 获取输出信息的代码的位置
String location = getCodeLocation();
// 是否是异常
if (obj instanceof Exception) {
Exception e = (Exception) obj;
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
String str = sw.toString();
log.info(location + str);
} else {
log.info(location + obj.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 打印警告
*
* @param obj
*/
public static void warn(Object obj) {
try {
// 获取输出信息的代码的位置
String location = getCodeLocation();
// 是否是异常
if (obj instanceof Exception) {
Exception e = (Exception) obj;
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
String str = sw.toString();
log.warn(location + str);
} else {
log.warn(location + obj.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 打印错误
*
* @param obj
*/
public static void error(Object obj) {
try {
// 获取输出信息的代码的位置
String location = getCodeLocation();
// 是否是异常
if (obj instanceof Exception) {
Exception e = (Exception) obj;
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
String str = sw.toString();
log.error(location + str);
} else {
log.error(location + obj.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取调用此函数的代码的位置
*
* @return
*/
public static String getCodeLocation() {
StringBuffer sb = new StringBuffer();
try {
// 获取输出信息的代码的位置
StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
// 类名
sb.append(stacks[3].getClassName());
sb.append("-");
// 方法名
sb.append(stacks[3].getMethodName());
// 行号
sb.append("(line: " + stacks[3].getLineNumber() + ")");
} catch (Exception e) {
}
return sb.toString();
}
}
2、效果演示
下面1/0会抛异常
@Controller
public class HelloWorldController {
@Autowired
private ISysUserService sysUserService;
@Autowired
private AsyncDemo asyncDemo;
@RequestMapping("/hello")
@ResponseBody
public String sayHello() {
int i = 1 / 0;
return "Hello World!";
}
}
访问localhost:8080/sbd/hello
后台的日志信息
日志文件的日志信息