背景:
常见代码中使用try&&catch捕获处理异常,仅针对代码块。若没有全局异常处理,系统出现未处理的异常时会直接返异常信息,影响用户体验。
(一)定义异常信息
定义异常信息操作接口
public interface BaseErrorInfoInterface {
public String getResultCode();
public String getResultMessage();
}
定义枚举类封装系统常见异常信息,实现异常信息操作接口
public enum BaseErrorEnum implements BaseErrorInfoInterface{
SUCCESS("200","操作成功!"),
FAIL("500","操作失败!"),
INTERNAL_SERVER_ERROR("500", "服务器内部错误!"),
BODY_NOT_MATCH("400","请求数据格式不合规!"),
NOT_FOUND("404", "未找到该资源!"),
SERVER_BUSY("503","服务器正忙,请稍后再试!")
;
private String resultCode;
private String resultMessage;
BaseErrorEnum( String resultCode, String resultMessage) {
this.resultCode = resultCode;
this.resultMessage = resultMessage;
}
@Override
public String getResultCode() {
return resultCode;
}
@Override
public String getResultMessage() {
return resultMessage;
}
}
(二)自定义异常,继承运行时异常。新增带参构造函数,方便使用自定义的异常信息。
public class BizException extends RuntimeException{
/**
* 错误码
*/
protected String errorCode;
/**
* 错误信息
*/
protected String errorMsg;
public BizException() {
super();
}
public BizException(BaseErrorInfoInterface errorInfoInterface) {
super(errorInfoInterface.getResultCode());
this.errorCode = errorInfoInterface.getResultCode();
this.errorMsg = errorInfoInterface.getResultMessage();
}
public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
super(errorInfoInterface.getResultCode(), cause);
this.errorCode = errorInfoInterface.getResultCode();
this.errorMsg = errorInfoInterface.getResultMessage();
}
public BizException(String errorMsg) {
super(errorMsg);
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg) {
super(errorCode);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg, Throwable cause) {
super(errorCode, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}
(三)定义返回消息体,定义常用的状态方法
public class ReturnDTO {
private Object message;
private String code;
private String desc;
public ReturnDTO() {
}
public ReturnDTO(BaseErrorInfoInterface errorInfo) {
this.code = errorInfo.getResultCode();
this.message = errorInfo.getResultMessage();
}
public Object getMessage() {
return message;
}
public void setMessage(Object message) {
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
/**
* 成功
*
* @return
*/
public static ReturnDTO success() {
return success(null);
}
/**
* 成功
* @param data
* @return
*/
public static ReturnDTO success(Object data) {
ReturnDTO rb = new ReturnDTO();
rb.setCode(BaseErrorEnum.SUCCESS.getResultCode());
rb.setDesc(BaseErrorEnum.SUCCESS.getResultMessage());
rb.setMessage(data);
return rb;
}
/**
* 失败
*/
public static ReturnDTO error(BaseErrorInfoInterface errorInfo) {
ReturnDTO rb = new ReturnDTO();
rb.setCode(errorInfo.getResultCode());
rb.setDesc(errorInfo.getResultMessage());
rb.setMessage(null);
return rb;
}
/**
* 失败
*/
public static ReturnDTO error(String code, String message) {
ReturnDTO rb = new ReturnDTO();
rb.setCode(code);
rb.setDesc(message);
rb.setMessage(null);
return rb;
}
/**
* 失败
*/
public static ReturnDTO error( String message) {
ReturnDTO rb = new ReturnDTO();
rb.setCode("500");
rb.setDesc(message);
rb.setMessage(null);
return rb;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
(四)定义全局异常处理类,注意理解使用注解@ControllerAdvice
@ControllerAdvice
public class ExceptionHandler {
/**
* 处理自定义的业务异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
@ResponseBody
public ReturnDTO bizExceptionHandler(HttpServletRequest req, BizException e){
log.error("全局异常捕获-发生的业务异常是:{}",e.getErrorMsg());
return ReturnDTO.error(e.getErrorCode(),e.getErrorMsg());
}
/**
* 处理空指针的异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public ReturnDTO nullPointExceptionHandler(HttpServletRequest req,NullPointerException e){
log.error("全局异常捕获-空指针异常是:",e);
return ReturnDTO.error(BaseErrorEnum.INTERNAL_SERVER_ERROR);
}
/**
* 处理其他异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =Exception.class)
@ResponseBody
public ReturnDTO exceptionHandler(HttpServletRequest req, Exception e){
log.error("全局异常捕获-未知异常!原因是:",e);
return ReturnDTO.error(BaseErrorEnum.INTERNAL_SERVER_ERROR);
}
}
测试方法
public void test01(){
//触发自定义异常
throw new BizException(BaseErrorEnum.BODY_NOT_MATCH);
//触发空指针异常
String str = null;
str.equals("111");
//触发其他异常
String str2 = "123abc";
Integer.parseInt(str2);
}