赞
踩
对可预知异常和不可预知异常的处理方案:
1、自定义异常类型。
2、自定义错误代码及错误信息。
3、对于可预知的异常由程序员在代码中主动抛出,由SpringMVC统一捕获。
可预知异常是程序员在代码中手动抛出本系统定义的特定异常类型,由于是程序员抛出的异常,通常异常信息比较
齐全,程序员在抛出时会指定错误代码及错误信息,获取异常信息也比较方便。
4、对于不可预知的异常(运行时异常)由SpringMVC统一捕获Exception类型的异常。
不可预知异常通常是由于系统出现bug、或一些不要抗拒的错误(比如网络中断、服务器宕机等),异常类型为
RuntimeException类型(运行时异常)。
5、可预知的异常及不可预知的运行时异常最终会采用统一的信息格式(错误代码+错误信息)来表示,最终也会随请求响应给客户端。
处理步骤流程:
1、在controller、service、dao中程序员抛出自定义异常;springMVC框架抛出框架异常类型
2、统一由异常捕获类捕获异常,并进行处理
3、捕获到自定义异常则直接取出错误代码及错误信息,响应给用户。
4、捕获到非自定义异常类型首先从Map中找该异常类型是否对应具体的错误代码,如果有则取出错误代码和错误
信息并响应给用户,如果从Map中找不到异常类型所对应的错误代码则统一为99999错误代码并响应给用户。
5、将错误代码及错误信息以Json格式响应给用户。
//添加页面
public CmsPageResult add(CmsPage cmsPage){
//校验页面是否存在,根据页面名称、站点Id、页面webpath查询
CmsPage cmsPage1 = cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(), cmsPage.getSiteId(), cmsPage.getPageWebPath());
if(cmsPage1==null){
cmsPage.setPageId(null);//添加页面主键由spring data 自动生成
cmsPageRepository.save(cmsPage);
//返回结果
CmsPageResult cmsPageResult = new CmsPageResult(CommonCode.SUCCESS,cmsPage);
return cmsPageResult;
}
return new CmsPageResult(CommonCode.FAIL,null);
}
1、上边的代码只要操作不成功仅向用户返回“错误代码:11111,失败信息:操作失败”,无法区别具体的错误信
息。
2、service方法在执行过程出现异常在哪捕获?在service中需要都加try/catch,如果在controller也需要添加
try/catch,代码冗余严重且不易维护。
1、在Service方法中的编码顺序是先校验判断,有问题则抛出具体的异常信息,最后执行具体的业务操作,返回成
功信息。
2、在统一异常处理类中去捕获异常,无需controller捕获异常,向用户返回统一规范的响应信息。
自定义异常类:
package com.xuecheng.framework.exception; import com.xuecheng.framework.model.response.ResultCode; /** * 自定义异常类型 */ public class CustomException extends RuntimeException { //异常错误代码 ResultCode resultCode; public CustomException(ResultCode resultCode){ this.resultCode = resultCode; } public ResultCode getResultCode(){ return this.resultCode; } }
异常抛出类:
package com.xuecheng.framework.exception;
import com.xuecheng.framework.model.response.ResultCode;
/**
* 异常抛出类
*/
public class ExceptionCast {
public static void cast(ResultCode resultCodeObj){
throw new CustomException(resultCodeObj);
}
}
异常捕获类:
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; import org.springframework.web.bind.annotation.ResponseBody; /* 统一异常捕获类 */ @ControllerAdvice//控制器增强,用于捕获异常的控制器注解. public class ExceptionCatch { //定义一个Logger日志记录变量,用于异常(由捕获类所产生的)日志. private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class); @ExceptionHandler(CustomException.class) // 括号内为异常抛出类,只要遇到CustomException这个类抛出的异常,就去捕获. @ResponseBody //用于将异常信息以Json字符串的形式响应到前端. public ResponseResult customExceptionOfResponseResult(CustomException customException){ //记录日志 LOGGER.error("catch exception:{}",customException.getMessage()); ResultCode resultCode = customException.getResultCode(); return new ResponseResult(resultCode); } }
要使用到异常的方法:
// 新增页面 public CmsPageResult add(CmsPage cmsPage){ //1.检查页面是否存在 通过查询页面名称,站点id,页面webpath(虚拟路径)实现效验. CmsPage cmsPageResult = cmsPageRepositoryObj.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(), cmsPage.getSiteId() ,cmsPage.getPageWebPath() ); if (cmsPageResult != null){//如果不为空,则说明存在该页面,无法新增 //抛出异常 ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME); } //如果为空则说明数据库不存在该页面,则可以添加 cmsPage.setPageId(null);//对页面主键传递空参数,由spring data自动生成 cmsPageRepositoryObj.save(cmsPage); //将其形参出接收到的Controller层传来的数据保存到mongoDB数据库 //返回结果到controller层 return new CmsPageResult(CommonCode.SUCCESS,cmsPage); }
异常捕获类:
注意:不可预知的异常捕获类并没有捕获你自定义的抛出异常类,而是直接捕获最高级别的’Exception.Class’异常.所以无论是需求上还是逻辑上都不需要应用到@自定义异常类型的类,以及@抛出异常的类.
因为只要某个业务层(如PageService这个类)触发(发生)了异常,那么就意味着触发了Exception.Class(因为所有异常都继承于它),进而就会触发本异常捕获类.
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.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /* 统一异常捕获类 */ @ControllerAdvice//控制器增强,用于捕获异常的控制器注解. public class ExceptionCatch { //定义一个Logger日志记录变量,用于异常(由捕获类所产生的)日志. private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class); //定义用于容纳异常类型的Map,存放异常类型所对应的错误代码. private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS; //定义上面map的builder对象,去构建上面的ImmutableMap protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builderObj = ImmutableMap.builder(); static { //为该对象异常类型(class)和对应的异常代码 builderObj.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM); } @ExceptionHandler(Exception.class) // 括号内为异常抛出类,只要遇到CustomException这个类抛出的异常,就去捕获. @ResponseBody //用于将异常信息以Json字符串的形式响应到前端. public ResponseResult customExceptionOfResponseResult(Exception e){ //记录日志 LOGGER.error("catch exception:{}",e.getMessage()); if (EXCEPTIONS == null){//如果尚未构建用于处理未知异常的ImmutableMap对象,则进行构建 EXCEPTIONS = builderObj.build();//构建! } // 从EXCEPTIONS中寻找异常类型对应的错误代码,如果找到了将错误代码响应给用户,如果找不到就返回给用户9999 final ResultCode resultCode = EXCEPTIONS.get(e.getClass()); if (resultCode != null){//判断是否为未知异常.肺空(即map中获取不到这种类型的异常类)则为未知异常 return new ResponseResult(resultCode);//如果为未知异常,则返回CommonCode的 10003,"非法参数!" }else { return new ResponseResult(resultCode);//如果不为空,则是不为未知异常,而为更大的不可预知的异常,则返回CommonCode的 99999,"抱歉,系统繁忙,请稍后重试!" //当然,我们可以在map集合中添加此异常的异常class类,同时添加对应的异常代码和字符串信息.这个要根据具体的业务需求来编写了. } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。