异常的处理
问题:
当我们不对异常进行处理的时候,服务器端的异常就会原封不动的给返回前端页面,这是没有意义的行为,而且对用户也不够友好
就算我们自定义了返回的结果信息,也只是包含了正确与错误的信息,并没有具体的信息,在页面显示确实也不大友好
解决思路:
异常是不可以避免的,分为两种,一种是我们可以预知的异常.我们可以针对这种来自定义异常,并处理
一种是不可以预知的异常,比如系统运行时候由于不可抗因素产生的的异常
1. 对可以预知的异常(比如空指针,对象已经存在...)进行自定义异常类,并在可能发生异常的地方抛出异常
2. 由于springMVC的机制,我们可以在表现层捕捉到业务层以及持久层的异常信息,所以,我们可以使用springMVC控制增强
对异常进行统一的异常处理
3. 在统一的异常处理中,分别对自定义的异常以及不可预知的异常进行处理
示例:
自定义异常类:CustomException(用来抛出可预知的异常)
/**
* 自定义异常类
* Created by Levi on 2018/12/1.
*/
public class CustomException extends RuntimeException{
//错误代码(包含了错误代码,与错误信息)
private ResultCode resultCode;
public CustomException(ResultCode resultCode) {
//异常信息为错误代码+异常信息
super("错误代码:"+resultCode.code()+"错误信息:"+resultCode.message());
this.resultCode = resultCode;
}
public ResultCode getResultCode() {
return resultCode;
}
}
自定义异常抛出类:ExceptionCast
也可以不定义,直接抛出,这里只是抽取出来
/**
* 异常抛出类
* Created by Levi on 2018/12/1.
*/
public class ExceptionCast {
//抛出自定义异常
public static void cast(ResultCode resultCode){
throw new CustomException(resultCode);
}
}
使用springMVC控制增强统一捕获处理异常:
/**
* 定义一个异常捕获类
* Created by Levi on 2018/12/1.
*/
//springMVC控制增强注解,即异常通知注解
@ControllerAdvice
public class ExceptionCatch {
//日志打印对象
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
//定义ImmutableMap来存放异常类型与错误代码的映射,ImmutableMap的特点的一旦创建不可改变,并且线程安全
//就是定义一个key存放异常类字节码,value存放错误代码的map集合
private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
//使用builder来构建一个异常类型和错误代码的异常
protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder =
ImmutableMap.builder();
//捕获不可预知的异常Exception
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult customException(Exception e){
//出现错误,日志输出
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
//健壮性判断并初始化EXCEPTIONS
if (EXCEPTIONS == null){
EXCEPTIONS = builder.build();
}
//根据字节码查询错误代码
final ResultCode resultCode = EXCEPTIONS.get(e.getClass());
final ResponseResult responseResult;
if (resultCode != null){
//如果可以找到错误代码,返回错误代码
responseResult = new ResponseResult(resultCode);
}else {
//如果找不到,就返回99999,服务器错误
responseResult = new ResponseResult(CommonCode.SERVER_ERROR);
}
return responseResult;
}
//捕获自定义异常CustomException
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult customException(CustomException e){
//出现错误,日志输出
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
ResultCode resultCode = e.getResultCode();
return new ResponseResult(resultCode);
}
static {
//向异常集合中加入一些异常类型,这里的是后期对某些已经发生的未知异常进行处理
builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM);
}
}