本文共 5771 字,大约阅读时间需要 19 分钟。
一般异常处理并返回到客户端是因为客户端需要知道错误信息
如果不是这样的话,处理程序的内部异常一般打印日志去标记或者捕获一下就可以了打印日志:private static final Logger LOGGER = LoggerFactory.getLogger(PageService.class);
若添加try catch语句则程序会处理异常,try内异常不再执行,处理后继续向下运行
若没有try catch语句 程序会在异常处跳出来,不再运行下面部分
个人理解是你主动 throw 一个异常出来, 如果不用try cath 捕获的话, 下面的代码是不会执行的;
如果你当场用try cath捕获了, 下面的代码会继续执行。当你在Service层throw抛出了一个异常, 那么如果没有专门的异常捕获类, 异常就要交给Controller层去处理了,我们不希望Controller层处理异常, 所以要设置一个专门的异常捕获类
优点: 1、我们可以对异常信息进行详细描述, 使得返回客户端的信息有辨识度(不单纯发操作失败和错误代码) 2、捕获大部分异常, 减少try catch 代码冗余问题大概流程思想:
可预知:由程序员在代码有可能出错的地方手动抛出一个异常
不可预知:不可预知异常通常由SpringMVC或者第三方依赖等抛出的异常,程序员一般不可知package com.xuecheng.framework.exception;import com.xuecheng.framework.model.response.ResultCode;/** * @author Huang * @version 1.0 * @date 2020/3/27 10:49 */public class CustomException extends RuntimeException { private ResultCode resultCode; public CustomException(){ } public CustomException(ResultCode resultCode){ //异常信息为错误代码+异常信息 super("错误代码:"+resultCode.code()+"错误信息:"+resultCode.message()); this.resultCode = resultCode; } public ResultCode getResultCode(){ return resultCode; }}
1、注意此处的自定义异常类是继承RuntimeException,而不是Exception。 如果继承Exception, 当你throw new Exception时, 程序编译时会要求你在方法处抛出该异常或者用try catch捕获该异常, 对代码有侵入性,而RuntimeException不会有上述要求
2、一定要写super("…");否则会报空指针异常 3、ResultCode resultCode 是异常的返回消息, 返回给客户端即可看到错误的详情信息package com.xuecheng.framework.exception;import com.xuecheng.framework.model.response.ResultCode;/** * @author Huang * @version 1.0 * @date 2020/3/27 11:00 *///对抛出异常代码进行包装, 使其使用的更简洁(其实区别不大)public class ExceptionCast { public static void cast(ResultCode resultCode){ throw new CustomException(resultCode); }}
不包装的抛出异常
throw new CustomException(resultCode)
包装后的抛出异常
ExceptionCast.cast(resultCode);
if(null!=byPageNameAndSiteIdAndPageWebPath){ ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME);}
注:CmsCode.CMS_ADDPAGE_EXISTSNAME是一个resultCode的实现枚举类对象
package com.xuecheng.framework.exception;import com.xuecheng.framework.model.response.ResponseResult;import com.xuecheng.framework.model.response.ResultCode;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;/** * 自定义异常统一捕获器 * @author Huang * @version 1.0 * @date 2020/3/27 11:04 */@ControllerAdvice //控制器增强public class ExceptionCatch { private static final Logger logger = LoggerFactory.getLogger(ExceptionCatch.class); //捕获可预知自定义CustomException类异常的方法 @ResponseBody @ExceptionHandler(CustomException.class) public ResponseResult handlerCustomException(CustomException customException){ //记录日志 logger.error("捕获到一个可预知异常:" + customException.getMessage()); //获取该异常的代码 ResultCode resultCode = customException.getResultCode(); //返回结果响应体 return new ResponseResult(resultCode); }}
package com.xuecheng.framework.exception;import com.google.common.collect.ImmutableMap;import com.xuecheng.framework.model.response.CommonCode;import com.xuecheng.framework.model.response.ResponseResult;import com.xuecheng.framework.model.response.ResultCode;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.context.properties.bind.BindException;import org.springframework.http.converter.HttpMessageNotReadableException;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;/** * 自定义不可预知异常统一捕获器 * @author Huang * @version 1.0 * @date 2020/3/27 11:04 */@ControllerAdvice //控制器增强public class ExceptionCatch { private static final Logger logger = LoggerFactory.getLogger(ExceptionCatch.class); //定义exceptionsMap, 存放异常类型和错误代码信息对应key-value //ImmutableMap的特点的一旦创建不可改变,并且线程安全 private static ImmutableMap, ResultCode> exceptionsMap; //定义exceptionsMap的builder对象,通过builder存放数据后再赋值给exceptionsMap,构建exceptionsMap protected static ImmutableMap.Builder , ResultCode> builder = ImmutableMap.builder(); //静态方法体, 每次程序运行后,该类只会执行一次 //初始化builder中不可预知异常类的对应错误信息 static { builder.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM); //缺少实体参数 } //不可预知异常通常由SpringMVC或者第三方依赖等抛出的异常,程序员一般不可知 //捕获并设置返回信息 //捕获不可预知自定义Exception类异常的方法 @ResponseBody @ExceptionHandler(BindException.class) public ResponseResult handlerException(Exception exception){ //记录日志 logger.error("捕获到一个不可预知异常:" + exception.getMessage()); if(null==exceptionsMap){ exceptionsMap = builder.build(); //exceptionsMap构建成功 } ResultCode resultCode = exceptionsMap.get(exception.getClass()); //获取对应异常的对应错误信息 ResponseResult responseResult; //找到了对应的错误信息 if(null!=resultCode){ responseResult = new ResponseResult(resultCode); } else{ responseResult = new ResponseResult(CommonCode.SERVER_ERROR); } //返回结果响应体 return responseResult; }}
注:这里的 ImmutableMap 是一个泛型的Map,因为不可预知的异常有N多种,所以要用?泛型来装载这些异常类型(Throwable是所有Exception的父类)
0、 ImmutableMap的特点的一旦创建不可改变,并且线程安全 1、ImmutableMap ----- exceptionsMap:存放异常类型和错误代码信息对应key-value 2、builder对象:通过builder存放数据后再赋值给exceptionsMap,构建exceptionsMap 3、statIc方法块中的就是初始化builder了,Key是异常的类, Value是错误信息@ControllerAdvice (增强控制器)代表了全局处理,可以全局处理数据,全局处理异常等。这里运用于全局异常处理, 表示这个类是全局可以访问的。 @ExceptionHandler(UserNoExit.class)表示该方法只处理该异常类型
@ResponseBody表示以json格式返回消息体到客户端转载地址:http://ruern.baihongyu.com/