通常在項目裏,會用大catch包住異常,但是這麼做在生產上將影響問題定位;爲了在項目中更規範的進行編碼,本文將詳細介紹如何基於AOP來實現異常攔截
處理結果:
404請求異常
請求參數異常
一、開啓AspectJ的Proxy設置,使得SpringBoot容器可以解析aop配置
@EnableAspectJAutoProxy(proxyTargetClass = true)
二、定義通用返回邏輯
2.1 通用返回類 CommonRes.class
package com.yfy.dianping.common;
/**
* @author youfy
*/
public class CommonRes {
/**
*請求的返回處理結果,"success"或"fail"
*/
private String status;
/**
* 若status=success時,表明對應的返回的json類數據
* 若status=fail時,則data內將使用通用的錯誤碼對應的格式
*/
private Object data;
/**
*定義一個通用的創建返回對象的方法
*/
public static CommonRes create(Object result){
return CommonRes.create(result,"success");
}
public static CommonRes create(Object result,String status){
CommonRes commonRes = new CommonRes();
commonRes.setStatus(status);
commonRes.setData(result);
return commonRes;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
2.2 通用異常類 CommonError.class
package com.yfy.dianping.common;
/**
* @author youfy
*/
public class CommonError {
/**
* 錯誤碼
*/
private Integer errCode;
/**
* 錯誤描述
*/
private String errMsg;
public CommonError(Integer errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public CommonError(EmBusinessError emBusinessError){
this.errCode = emBusinessError.getErrCode();
this.errMsg = emBusinessError.getErrMsg();
}
public Integer getErrCode() {
return errCode;
}
public void setErrCode(Integer errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}
2.3業務異常 BusinessException.class
package com.yfy.dianping.common;
/**
* @author youfy
*/
public class BusinessException extends Exception {
private CommonError commonError;
public BusinessException(EmBusinessError emBusinessError){
super();
this.commonError = new CommonError(emBusinessError);
}
public CommonError getCommonError() {
return commonError;
}
public void setCommonError(CommonError commonError) {
this.commonError = commonError;
}
}
2.4 異常枚舉 EmBusinessError.class
package com.yfy.dianping.common;
/**
* @author youfy
*/
public enum EmBusinessError {
//通用的錯誤類型以10000開頭
NO_OBJECT_FOUND(10001, "請求對象不存在"),
UNKNOWN_ERROR(10002, "未知異常"),
NO_HANDLE_FOUND(10003, "找不到執行的路徑操作"),
BIND_EXCEPTION_ERROR(10004, "請求參數錯誤"),
;
private Integer errCode;
private String errMsg;
EmBusinessError(Integer errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public Integer getErrCode() {
return errCode;
}
public void setErrCode(Integer errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}
三、定義全局異常處理器,使用@ControllerAdvice可覆蓋所有controller
全局異常處理器 GlobalExceptionHandler.class
package com.yfy.dianping.common;
import org.springframework.web.bind.ServletRequestBindingException;
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.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author youfy
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonRes doError(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,
Exception ex) {
if (ex instanceof BusinessException) {
return CommonRes.create(((BusinessException) ex).getCommonError(), "fail");
} else if (ex instanceof NoHandlerFoundException) {
CommonError commonError = new CommonError(EmBusinessError.NO_HANDLE_FOUND);
return CommonRes.create(commonError, "fail");
} else if (ex instanceof ServletRequestBindingException) {
CommonError commonError = new CommonError(EmBusinessError.BIND_EXCEPTION_ERROR);
return CommonRes.create(commonError, "fail");
} else {
CommonError commonError = new CommonError(EmBusinessError.UNKNOWN_ERROR);
return CommonRes.create(commonError, "fail");
}
}
}
四、處理404請求異常,設置:拒絕404默認的處理,如果沒找到處理器就拋出異常
application.properties下配置:
spring.resources.add-mappings=true
spring.mvc.throw-exception-if-no-handler-found=true
五、處理請求參數異常,用ServletRequestBindingException捕獲
if (ex instanceof NoHandlerFoundException) {
CommonError commonError = new CommonError(EmBusinessError.NO_HANDLE_FOUND);
return CommonRes.create(commonError, "fail");
}