统一异常处理

为什么需要做统一异常处理:
因为如果不做统一处理,返回与前端的数据会非常乱,前端不好处理;并且不做统一处理,controller层就要写很多的重复代码。
统一格式:
{
     "code":10001,
     "msg":"异常信息",
     "data":null	 
}

{
     "code":10000,
     "msg":"SUCCESS",
     "data":{
	 "id":20,
	 "name":"test",
	 "age":18
      }	
}
实现步骤:
  1. 新建Result对象——也就是请求返回的整体对象,包括code,msg,data
public class Result {
	private Integer code ;
	private String msg;
	private T data;
	public Integer getCode() {
		return code;
	}
	public void setCode(Integer code) {
		this.code = code;
	}
	public String getMsg() {
		return msg;
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
	public T getData() {
		return data;
	}
	public void setData(T data) {
		this.data = data;
	}
	
}

2.增加ResultUtil方法,封装设置Result数据的操作
/**
 * @author Qi.Zhang
 * 类说明:为避免controller层重复的set操作,遂添加ResultUtil
 */
public class ResultUtil {
	//成功,有返回值
	public static Result success(Object object){
		Result result = new Result();
		result.setCode(10000);
		result.setMsg("SUCCESS");
		result.setData(object);
		return result;
	}
	//成功,没有返回值
	public static Result success(){
		return success(null);
	}
	//失败
	public static Result error(Integer code , String errorMsg){
		Result result = new Result();
		result.setCode(code);
		result.setMsg(errorMsg);
		return result;
	}	
}
3.统一异常处理
/**
 * 
 * @author Qi.Zhang
 * 类说明:统一异常处理
 * 		Service抛异常到Controller,Controller继续抛异常
 * 		最终异常被这里捕获
 * 		我们让异常信息变成符合Result规范的数据格式
 */
@ControllerAdvice
public class ExceptionHandle {
	
	@ExceptionHandler(value = Exception.class)//定义捕获异常的类型
	@ResponseBody// 因为不是RestController,所以需要加这个,让它返回json格式
	public Result handler(Exception e){
		return ResultUtil.error(10001, e.getMessage());
	}
}
4.使用枚举统一管理异常信息(是必要的)
/**
 * @author Qi.Zhang
 * 类说明:使用枚举统一维护信息
 */
public enum ResultEnum {
	SUCCESS(10000,"SUCCESS"),
	UNKNOWN_ERROR(10002,"未知错误")
	;
	
	private Integer code;
	private String msg;
	
	private ResultEnum(Integer code, String msg) {
		this.code = code;
		this.msg = msg;
	}

	public Integer getCode() {
		return code;
	}

	public String getMsg() {
		return msg;
	}
}


        5.区分系统异常以及自定义异常捕获
注意:自定义异常需要 extends RuntimeException;
        原因:spring只对RuntimeException才进行事物回滚,Exception不管的
  • 自定义异常
/**
 * @author Qi.Zhang
 * 类说明:自定义异常
 */
public class MyException extends RuntimeException {
	private Integer code;

	//自定义异常code 异常消息
	public MyException(Integer code,String message) {
		super(message);
		this.code = code;
	}
	//从枚举中获取定义好的信息
	public MyException(ResultEnum e) {
		super(e.getMsg());
		this.code = e.getCode();
	}

	public Integer getCode() {
		return code;
	}

	public void setCode(Integer code) {
		this.code = code;
	}
	
}
  • 改造第3步,完善统一异常处理
/**
 * 
 * @author Qi.Zhang
 * 类说明:统一异常处理
 * 		Service抛异常到Controller,Controller继续抛异常
 * 		最终异常被这里捕获
 * 		我们让异常信息变成符合Result规范的数据格式
 */
@ControllerAdvice
public class ExceptionHandler {
	//在日志中记录异常
	private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
	
	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public Result handler(Exception e){
		if (e instanceof MyException) {
			MyException myException = (MyException)e;
			return ResultUtil.error(myException.getCode(), myException.getMessage());
		}
		logger.error("系统异常{}",e);
		return ResultUtil.error(10001, e.getMessage());
	}
}
使用
@GetMapping(value="/healthLevelData")
public String getHealthLevelData(){
      return new Gson().toJson(ResultUtil.success(dimCacheImpl.getDimHealthLevelList()));
}










你可能感兴趣的:(springboot,异常,统一异常处理)