统一异常处理

时间:2021-12-21 00:50:36
为什么需要做统一异常处理:
因为如果不做统一处理,返回与前端的数据会非常乱,前端不好处理;并且不做统一处理,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<T> {	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规范的数据格式 */@ControllerAdvicepublic 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规范的数据格式 */@ControllerAdvicepublic 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()));}