介绍基于SpringBoot项目三种统一异常处理方案,更优雅的处理全局的异常。
实现 HandlerExceptionResolver 接口
顾名思义,HandlerExceptionResolver
是异常解析器处理器的意思,通过实现其提供的resolveException
方法,HandlerExceptionResolver
可以解析并捕获到Controller
层抛出的所有异常,方便我们统一处理,代码示例如下:
@Component
public class SysHandlerExceptionResolver implements HandlerExceptionResolver {
private static final Logger logger = LoggerFactory.getLogger(SysHandlerExceptionResolver.class);
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
logger.error(request.getRequestURL().toString(), e);
if (e instanceof BusinessException) {
ModelAndView modelAndView = new ModelAndView("businessException");
modelAndView.addObject("errorMsg", e.getMessage());
return modelAndView;
} else {
ModelAndView modelAndView = new ModelAndView("sysException");
modelAndView.addObject("errorMsg", e.getMessage());
return modelAndView;
}
}
}
总结步骤如下:
1、定义一个SysHandlerExceptionResolver
实现 HandlerExceptionResolver
,加上 @Component
,交给spring容器管理
2、在 resolveException
方法中统一对异常进行处理,打印日志信息和异常堆栈
3、根据异常的类型去匹配到你定义的业务异常BusinessException
或者其他异常,返回不同的模型视图ModelAndView
如果是想返回JSON数据也是可以做到的,可以利用response的输出流进行输出::
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
logger.error(request.getRequestURL().toString(), e);
if (e instanceof BusinessException) {
Playload error = Playload.error(RespCode.BUSINESS_EX.getCode(), e.getMessage());
try {
response.setContentType("application/json; charset=utf-8");
response.getWriter().write(JSON.toJSONString(error));
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
Playload error = Playload.error(RespCode.OTHER_EX.getCode(), e.getMessage());
try {
response.setContentType("application/json; charset=utf-8");
response.getWriter().write(JSON.toJSONString(error));
} catch (IOException e1) {
e1.printStackTrace();
}
}
return new ModelAndView();
}
以上定义的统一返回对象Playload
、统一业务异常对象BusinessException
、统一响应码RespCode
的代码如下::
public class Playload<T> {
private Integer code;
private String msg;
private T data;
public Playload(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static Playload success(Object data) {
return new Playload(RespCode.SUCCESS.getCode(), RespCode.SUCCESS.getDesc(), data);
}
public static Playload success() {
return new Playload(RespCode.SUCCESS.getCode(), RespCode.SUCCESS.getDesc(), null);
}
public static Playload error(Integer code, String msg) {
return new Playload(code, msg, null);
}
// 省略getter和setter
}
public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
}
public enum RespCode {
SUCCESS(0, "成功"),
PARAM_ERROR(-1, "参数错误"),
BUSINESS_EX(-2, "业务异常"),
OTHER_EX(-3, "其他异常");
RespCode(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
private Integer code;
private String desc;
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
下一篇文章分享第二种处理方案~