背景: 实际开发项目中经常会出现一些事先没有考虑到或者不可控制的异常(比如数据库挂掉等),如果不对他处理的话,jvm会默认返回一个异常视图,并且会中断执行,这在项目中是不允许的,所以要对所有的可能出现异常的代码加try catch,但是try的性能相对来说是很差的,并且并不是每次都会出现异常,所以这样每次执行try都是在无形的消耗性能。为了应对这种情况,项目中一般会使用全局异常控制来处理。
1、自定义service层全局异常
package cn.vo;
/**
* Title: BusinessException
* @date 2018年9月10日
* @version V1.0
* Description: 业务层运行时异常封装
*/
public class BusinessException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
public BusinessException(String message){
super(message);
}
}
2、全局异常处理
package cn.config;
import java.sql.SQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.utils.R;
import cn.vo.BusinessException;
/**
* Title: GlobalExceptionHandler
* @date 2018年9月10日
* @version V1.0
* Description: 全局异常处理
*/
@ControllerAdvice//spring封装的增强控制器,最常用的组合用法是配合ExceptionHandler做异常处理
public class GlobalExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* @Description 处理所有不可知的异常(controller层)
* @date 2018年9月10日上午10:38:49
*/
@ExceptionHandler(Exception.class)//异常类注解,括号中不加类型会默认返回对应的异常类型
@ResponseBody
R handleException(Exception e){
LOGGER.error(e.getMessage(), e);
return R.error(e.getMessage());
}
/**
* @Description 处理所有业务异常(service层)
* @date 2018年9月10日上午10:38:12
*/
@ExceptionHandler(BusinessException.class)
@ResponseBody
R handleBusinessException(BusinessException e){
LOGGER.error(e.getMessage(), e);
return R.error(e.getMessage());
}
/**
* @Description 处理所有接口数据验证异常 (bean validate验证)
* @date 2018年9月10日上午10:38:02
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
R handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
LOGGER.error(e.getMessage(), e);
//bean validate会将整个对象的所有参数全部验证完,如果有不符合要求的参数会全部返回一个数组,项目中一般会具体取出哪个参数不合法
return R.error(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
}
/**
* @Description 处理所有SQL异常 (持久层sql异常)
* @date 2018年9月10日上午10:38:02
*/
@ExceptionHandler(SQLException.class)
@ResponseBody
R handleSQLException(SQLException e){
LOGGER.error(e.getMessage(), e);
return R.error("服务器繁忙,请稍后重试");
}
}