开发之统一异常处理

系统对异常的处理使用统一的异常处理流程:
1、自定义异常类型。
2、自定义错误代码及错误信息。
3、对于可预知的异常由程序员在代码中主动抛出,由SpringMVC统一捕获。
可预知异常是程序员在代码中手动抛出本系统定义的特定异常类型,由于是程序员抛出的异常,通常异常信息比较
齐全,程序员在抛出时会指定错误代码及错误信息,获取异常信息也比较方便。
4、对于不可预知的异常(运行时异常)由SpringMVC统一捕获Exception类型的异常。
不可预知异常通常是由于系统出现bug、或一些不要抗拒的错误(比如网络中断、服务器宕机等),异常类型为
RuntimeException类型(运行时异常)。
5、可预知的异常及不可预知的运行时异常最终会采用统一的信息格式(错误代码+错误信息)来表示,最终也会随
请求响应给客户端。

详细步骤:

1、在controller、service、dao中程序员抛出自定义异常;springMVC框架抛出框架异常类型
2、统一由异常捕获类捕获异常,并进行处理
3、捕获到自定义异常则直接取出错误代码及错误信息,响应给用户。

4、捕获到非自定义异常类型首先从Map中找该异常类型是否对应具体的错误代码,如果有则取出错误代码和错误
信息并响应给用户,如果从Map中找不到异常类型所对应的错误代码则统一为99999错误代码并响应给用户。
5、将错误代码及错误信息以Json格式响应给用户。

代码实现并测试:

1.自定义异常抛出类参数:code、message、successage@ToString

public enum CmsCode implements ResultCode {
CMS_ADDPAGE_EXISTSNAME(false,24001,"页面名称已存在!")
CMS_PAGE_NOTEXIST(false,24006,"页面不存在!"),
UPDATE_FAILD(false,24008,"更新页面失败!");
//操作代码
boolean success;
//操作代码
int code;
//提示信息
String message;

 

2.自定义异常抛出类

 

@Data
public class CustomException extends RuntimeException {

//返回的代码
private ResultCode resultCode;

public CustomException(ResultCode resultCode) {
//异常信息为错误代码+异常信息
super("错误代码:"+resultCode.code()+"错误信息:"+resultCode.message());
this.resultCode = resultCode;
}

3.自定义捕获异常,然后全局处理 (这里要主要相面的注解,这几个注解比较重要,加上注解,抛出异常后就会监听到,然后调用这个方法,最后返回给用户)
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;

/**
* 全局捕获异常类:只要作用在@RequestMapping上,所有的异常都会被捕获
*
*/
@ResponseBody //在下面添加也可以
@ControllerAdvice
public class ExceptionCatch {
private static final Logger logger = LoggerFactory.getLogger(ExceptionCatch.class);

//捕获ExceptionCast 异常
@ExceptionHandler(value = CustomException.class )
//这个注解是将参数转换成 json格式,否则会报错,因为这个是json格式
@ResponseBody
public ResponseResult customException(CustomException e) {
logger.error("catch exception : {}\r\n exception: ",e.getMessage(), e);
ResultCode resultCode = e.getResultCode();
ResponseResult responseResult = new ResponseResult(resultCode);
return responseResult;
}
}
4.抛出异常在此封装(不用每次都throw 异常,用一个类的静态方法进行抛出即可)
/**
* 抛出异常类
*/
public class ExceptionCast {
//使用此静态方法抛出自定义异常
public static void cast(ResultCode resultCode){
throw new CustomException(resultCode);
}
}
 
测试:
controller
@Override
@GetMapping("/get/{id}")
public CmsPage findById(@PathVariable("id") String id) {
return pageService.findById(id);
}

service:
  @Override
public CmsPage findById(String id) {
Optional<CmsPage> cmsPage = cmsPageRepository.findById(id);
if(cmsPage.isPresent()){
return cmsPage.get();
}
//这里抛出异常:调用抛出异常的方法:最后证明下面的代码不会执行。
ExceptionCast.cast(CmsCode.CMS_PAGE_NOTEXIST);
int a = 44;
a ++ ;
return new CmsPage();

return null;
}

/**
* 抛出异常类
*/
public class ExceptionCast {
//使用此静态方法抛出自定义异常
public static void cast(ResultCode resultCode){
//这里抛出异常,然后在全局捕获异常类就会捕获到这个异常
throw new CustomException(resultCode);
}

}

捕获异常:
@ResponseBody   //在下面添加也可以
@ControllerAdvice
public class ExceptionCatch {
private static final Logger logger = LoggerFactory.getLogger(ExceptionCatch.class);

//捕获ExceptionCast 异常
@ExceptionHandler(value = CustomException.class )
//这个注解是将参数转换成 json格式,否则会报错,因为这个是json格式
@ResponseBody
public ResponseResult customException(CustomException e) {
//这里打印日志
logger.error("catch exception : {}\r\n exception: ",e.getMessage(), e);
ResultCode resultCode = e.getResultCode();
ResponseResult responseResult = new ResponseResult(resultCode);
//这里直接放回异常给前端,异常执行结束。所以最开始调用抛出异常的那里下面的代码就不会执行了。
return responseResult;
}
}

结果:




 

 

posted @ 2019-10-12 10:12  BlakeYa  阅读(199)  评论(0编辑  收藏  举报