異常簡介
說明
一個開發框架少不了異常處理機制,讓所有的錯誤集中在一個地方處理,在業務代碼開發的時候,往外拋就可以了,由上層統一攔截處理、返回給調用方。這裏我們使用了自定義錯誤碼,並將錯誤碼定義在了錯誤碼枚舉類中,當然如果你的系統比較龐大,錯誤碼非常多,並且要實現錯誤碼的動態調整,那麼也可以將錯誤碼存在數據庫中,啓動後放到內存緩存,這裏爲了方便大家理解只是提前將錯誤碼定義在了枚舉類中。
UML圖
異常定義
錯誤碼定義
通過實現此接口擴展應用程序中的錯誤代碼
public interface ErrorCodeI {
public String getErrCode();
public String getErrDesc();
}
基礎錯誤碼定義
定義3個基本錯誤代碼
public enum BasicErrorCode implements ErrorCodeI {
BIZ_ERROR("BIZ_ERROR" , "通用的業務邏輯錯誤"),
ZCB_ERROR("ZCB_FRAMEWORK_ERROR" , "ZCB框架錯誤"),
SYS_ERROR("SYS_ERROR" , "未知的系統錯誤" );
private String errCode;
private String errDesc;
private BasicErrorCode(String errCode, String errDesc){
this.errCode = errCode;
this.errDesc = errDesc;
}
@Override
public String getErrCode() {
return errCode;
}
@Override
public String getErrDesc() {
return errDesc;
}
}
基礎異常信息定義
基異常是所有異常的父級,需要繼承運行時異常RuntimeException
public abstract class BaseException extends RuntimeException{
private static final long serialVersionUID = 1L;
private ErrorCodeI errCode;
public BaseException(String errMessage){
super(errMessage);
}
public BaseException(String errMessage, Throwable e) {
super(errMessage, e);
}
public ErrorCodeI getErrCode() {
return errCode;
}
public void setErrCode(ErrorCodeI errCode) {
this.errCode = errCode;
}
}
框架異常定義
擴展框架的基礎結構異常
public class ZCBException extends BaseException {
private static final long serialVersionUID = 1L;
public ZCBException(String errMessage){
super(errMessage);
this.setErrCode(BasicErrorCode.ZCB_ERROR);
}
public ZCBException(String errMessage, Throwable e) {
super(errMessage, e);
this.setErrCode(BasicErrorCode.ZCB_ERROR);
}
}
通用業務異常定義
擴展框架的業務已知異常
public class BizException extends BaseException {
private static final long serialVersionUID = 1L;
public BizException(String errMessage){
super(errMessage);
this.setErrCode(BasicErrorCode.BIZ_ERROR);
}
public BizException(ErrorCodeI errCode, String errMessage){
super(errMessage);
this.setErrCode(errCode);
}
public BizException(String errMessage, Throwable e) {
super(errMessage, e);
this.setErrCode(BasicErrorCode.BIZ_ERROR);
}
}
系統異常定義
擴展框架系統意外異常
public class SysException extends BaseException {
private static final long serialVersionUID = 4355163994767354840L;
public SysException(String errMessage){
super(errMessage);
this.setErrCode(BasicErrorCode.SYS_ERROR);
}
public SysException(ErrorCodeI errCode, String errMessage) {
super(errMessage);
this.setErrCode(errCode);
}
public SysException(String errMessage, Throwable e) {
super(errMessage, e);
this.setErrCode(BasicErrorCode.SYS_ERROR);
}
public SysException(String errMessage, ErrorCodeI errorCode, Throwable e) {
super(errMessage, e);
this.setErrCode(errorCode);
}
}
異常處理
異常處理接口定義
ExceptionHandlerI提供了一個後門,應用程序可以覆蓋默認的異常處理
public interface ExceptionHandlerI {
public void handleException(Command cmd, Response response, Exception exception);
}
異常處理工廠
這裏提供一種擴展機制,如果自己有實現異常處理機制,則執行自定義的異常處理,沒有就走默認的異常處理機制。
public class ExceptionHandlerFactory {
public static ExceptionHandlerI getExceptionHandler(){
try {
return ApplicationContextHelper.getBean(ExceptionHandlerI.class);
}
catch (NoSuchBeanDefinitionException ex){
return DefaultExceptionHandler.singleton;
}
}
}
默認異常處理
默認捕獲異常並打印日誌,並在對應的返回信息返回錯誤碼。
public class DefaultExceptionHandler implements ExceptionHandlerI {
private Log logger = LogFactory.getLog(ExtensionExecutor.class);
public static DefaultExceptionHandler singleton = new DefaultExceptionHandler();
@Override
public void handleException(Command cmd, Response response, Exception exception) {
buildResponse(response, exception);
printLog(cmd, response, exception);
}
private void printLog(Command cmd, Response response, Exception exception) {
if(exception instanceof BaseException){
//biz exception is expected, only warn it
logger.warn(buildErrorMsg(cmd, response));
}
else{
//sys exception should be monitored, and pay attention to it
logger.error(buildErrorMsg(cmd, response), exception);
}
}
private String buildErrorMsg(Command cmd, Response response) {
return "Process [" cmd "] failed, errorCode: "
response.getErrCode() " errorMsg:"
response.getErrMessage();
}
private void buildResponse(Response response, Exception exception) {
if (exception instanceof BaseException) {
ErrorCodeI errCode = ((BaseException) exception).getErrCode();
response.setErrCode(errCode.getErrCode());
}
else {
response.setErrCode(BasicErrorCode.SYS_ERROR.getErrCode());
}
response.setErrMessage(exception.getMessage());
response.setSuccess(false);
}
}
異常處理調用
在最上層框架進行調用,爲異常處理的總入口。
public Response invoke(Command command) {
Response response = null;
try {
preIntercept(command);
response = commandExecutor.execute(command);
}
catch(Exception e){
response = getResponseInstance(command);
response.setSuccess(false);
ExceptionHandlerFactory.getExceptionHandler().handleException(command, response, e);
}
finally {
//make sure post interceptors performs even though exception happens
postIntercept(command, response);
}
return response;
}
使用場景
系統異常
public static<T> T getBean(Class<T> targetClz){
T beanInstance = null;
//優先按type查
try {
beanInstance = (T) applicationContext.getBean(targetClz);
}catch (Exception e){
}
//按name查
if(beanInstance == null){
String simpleName = targetClz.getSimpleName();
//首字母小寫
simpleName = Character.toLowerCase(simpleName.charAt(0)) simpleName.substring(1);
beanInstance = (T) applicationContext.getBean(simpleName);
}
if(beanInstance == null){
new SysException(BasicErrorCode.SYS_ERROR, "Component " targetClz " can not be found in Spring Container");
}
return beanInstance;
}
業務異常
public static void notNull(Object object, ErrorCodeI errorCode, String message) {
if (object == null) {
throw new BizException(errorCode, message);
}
}
自定義異常
private void checkNull(BizScenario bizScenario){
if(bizScenario == null){
throw new ZCBException("BizScenario can not be null for extension");
}
}
個人網站:http://www.cnzcb.cn
本文由博客一文多發平臺 OpenWrite 發佈!