在统一异常处理的时候,要明确两点
1.自定义异常在哪里抛出
2.异常(自定义异常+不可预知异常)在哪里捕获
图要:
一、自定义异常
1.自定义异常需要继承RuntimeException
2.异常信息: 错误代码+异常信息
/**
自定义异常类
*/
public class CustomException extends RuntimeException{
//ResultCode 是一个返回信息接口,包含 是否成功、操作代码、提示信息
private ResultCode resultCode;
public CustomException (ResultCode resultCode){
//异常信息:错误代码+异常信息
super("错误代码:+"resultCode.code()+" 错误信息:"+resultCode.message());
this.resultcode = resultCode;
}
public ResultCode getResultCode(){
return this,resultCode;
}
}
异常抛出类
/**
异常抛出类
*/
public class ExceptionCast{
//使用此静态方法抛出异常
public static void cast(ResultCode resultCode){
throw new CustomException(resultCode);
}
}
二、异常捕获
1.@ControllerAdvice
2.@ExceptionHandler(要捕获的异常类.class)
/**
统一异常捕获类
*/
@ControllerAdvice
public class ExceptionCatch{
//记录日志
//...
//捕获CustomExeption异常
@ExceptionHandler(CustomException.class)
@ReponseBody//返回给前端
public ResponseResult customException(CustomException e){
//日志打印
// todo..
//获取异常信息,封装返回
ResultCode resultCode = e.getResultCode;
ResponseResult responseResult = new ResponseResult(resultCode);
return responseResult;
}
}
增加Exception异常捕获
思路:从map中找出异常类型对应的错误代码及错误信息,如果找到了,就存到ResultCode中,构建ResponseResult中返回,如果根据异常类型无法找到对应的错误代码及错误信息(ResultCode为空),则使用通用错误代码CommonCode构建ResponseResult返回
@ControllerAdvice
public class ExceptionCatch{
//使用EXCEPTIONS存放异常类型和错误代码的映射,ImmutableMap的特点是一旦创建,就不能改变,并且线程安全
private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
//使用builder来构建一个异常类型和错误代码异常
private static ImmutableMap.Builder<Class<? extend Throwable>,ResultCode> builder = ImmutableMap.builder();
static{
//这里添加一些基础的异常类型和错误代码 非法参数异常
builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM)
}
//捕获Exception异常
@ResponseBody
@ExceptionHandler(Exception.class)
public ResponseResult exception(Exception e){
//日志打印
//todo
//判断EXCEPTIONS是否为空
if(EXCEPTIONS == null){
EXCEPTIONS = builder.builder();
}
//根据异常类型从map中取出对应的错误代码
final ResultCode resultcode = EXCEPTIONS.get(e.getClass());
final ResponseResult responseResult;
if(resultCode != null){
responseResult = new ResponseResult(resultCode);
} else {
//在EXCEPTION中没有找到对应的异常类型及错误代码,就从通用错误代码类CommonCode中拿出
responseResult = new ResponseResult(CommonCode.SERVER_ERROR);
}
return responseResult;
}
}
注意:需要在SpringBoot启动类中添加对异常捕获类的扫描
三、自定义异常捕获测试
1.定义与业务相关联的的异常信息代码
@ToString
public enum CmsCode implements ResultCode{
CMS_ADDPAGE_EXISTS(false,24001,"页面已存在!");
//操作结果
boolean success;
//操作代码
int code;
//提示信息
String Message;
private CmsCode(boolean success,int code,String message){
this.success = success;
this.code = code;
this.message = message;
}
@Override
public boolean success(){
return success;
}
@Override
public int code(){
return code;
}
@Override
public String message(){
return message;
}
}
2.抛出自定义异常
/**
在添加页面之前,先去查询页面是否存在,如果存在就抛出页面已存在的自定义异常
*/
ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTS);