springboot全局异常封装案例
@ControllerAdvice三个场景:》https://www.cnblogs.com/lenve/p/10748453.html
- 全局异常处理
- 全局数据绑定
- 全局数据预处理
首先定义一个全局异常哪个接口,以备拓展使用 package com.wangbiao.common.exception.global; /** * TODO * * @author wangbiao * @Title 公共异常处理接口 * @module TODO * @description TODO * @date 2021/5/16 23:04 */ public interface BussinessException { String getResultCode(); /** 错误描述*/ String getResultMsg(); }
实现1中的接口,实现自己的异常构造与类型 package com.wangbiao.common.exception.global; import lombok.Data; /** * TODO * * @author wangbiao * @Title 自定义的异常类 * @module TODO * @description TODO * @date 2021/5/16 23:08 */ @Data public class Bussinesses extends RuntimeException{ /** * 错误码 */ protected String errorCode; /** * 错误信息 */ protected String errorMsg; public Bussinesses() { super(); } public Bussinesses(BussinessException errorInfoInterface) { super(errorInfoInterface.getResultCode()); this.errorCode = errorInfoInterface.getResultCode(); this.errorMsg = errorInfoInterface.getResultMsg(); } public Bussinesses(BussinessException errorInfoInterface, Throwable cause) { super(errorInfoInterface.getResultCode(), cause); this.errorCode = errorInfoInterface.getResultCode(); this.errorMsg = errorInfoInterface.getResultMsg(); } public Bussinesses(String errorMsg) { super(errorMsg); this.errorMsg = errorMsg; } public Bussinesses(String errorCode, String errorMsg) { super(errorCode); this.errorCode = errorCode; this.errorMsg = errorMsg; } public Bussinesses(String errorCode, String errorMsg, Throwable cause) { super(errorCode, cause); this.errorCode = errorCode; this.errorMsg = errorMsg; } public String getMessage() { return errorMsg; } @Override public Throwable fillInStackTrace() { return this; } }
定义一个常见异常的枚举,比如500,400,302等,在实际业务中可以把已知常见的异常类型进行封装 package com.wangbiao.common.exception.global; /** * TODO * * @author wangbiao * @Title 公共异常枚举类 * @module TODO * @description TODO * @date 2021/5/16 23:05 */ public enum CommonEnum implements BussinessException { SUCCESS("200", "正常!"), BODY_NOT_MATCH("400","数据格式不服!"), SIGNATURE_NOT_MATCH("401","签名验证失败!"), NOT_FOUND("404", "找不到!"), INTERNAL_SERVER_ERROR("500", "程序异常"), SERVER_BUSY("503","服务器。。。,请稍后再试!") ; private String resultCode; private String resultMsg; CommonEnum(String resultCode, String resultMsg) { this.resultCode = resultCode; this.resultMsg = resultMsg; } @Override public String getResultCode() { return resultCode; } @Override public String getResultMsg() { return resultMsg; } }
定义一个公共返回实体封装,这里统一把返回用json封装,正常结果返回,与异常可以封装返回客户端 package com.wangbiao.common.exception.global; import com.google.gson.Gson; import lombok.Data; /** * TODO * * @author wangbiao * @Title 自定义数据返回体 * @module TODO * @description TODO * @date 2021/5/16 23:10 */ @Data public class ResultBody { private static final Gson gson=new Gson(); /** * 响应代码 */ private String code; /** * 响应消息 */ private String message; /** * 响应结果 */ private Object result; public ResultBody() { } public ResultBody(BussinessException errorInfo) { this.code = errorInfo.getResultCode(); this.message = errorInfo.getResultMsg(); } /** * 响应成功 * * @return */ public static ResultBody success() { return success(null); } /** * 响应成功 * @param data * @return */ public static ResultBody success(Object data) { ResultBody rb = new ResultBody(); rb.setCode(CommonEnum.SUCCESS.getResultCode()); rb.setMessage(CommonEnum.SUCCESS.getResultMsg()); rb.setResult(data); return rb; } /** * 响应失败 */ public static ResultBody error(BussinessException errorInfo) { ResultBody rb = new ResultBody(); rb.setCode(errorInfo.getResultCode()); rb.setMessage(errorInfo.getResultMsg()); rb.setResult(null); return rb; } /** * 响应失败 */ public static ResultBody error(String code, String message) { ResultBody rb = new ResultBody(); rb.setCode(code); rb.setMessage(message); rb.setResult(null); return rb; } /** * 响应失败 */ public static ResultBody error( String message) { ResultBody rb = new ResultBody(); rb.setCode("-1"); rb.setMessage(message); rb.setResult(null); return rb; } @Override public String toString() { return gson.toJson(this); } }
一切就绪后,可以更具异常的类型进行分别处理与返回 package com.wangbiao.common.exception.global; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; /** * TODO * * @author wangbiao * @Title TODO * @module TODO * @description TODO * @date 2021/5/16 22:57 */ @ControllerAdvice @Slf4j public class MyGlobalExceptionHandler { /** * 处理自定义的业务异常 * @param req * @param e * @return */ @ExceptionHandler(value = Bussinesses.class) //@ExceptionHandler 注解用来指明异常的处理类型,即如果这里指定为 NullpointerException,则数组越界异常就不会进到这个方法中来 @ResponseBody public ResultBody bussiNessesHandler(HttpServletRequest req, Bussinesses e){ log.error("发生业务异常!原因是:{}",e.getErrorMsg()); return ResultBody.error(e.getErrorCode(),e.getErrorMsg()); } /** * 处理空指针的异常 * @param req * @param e * @return */ @ExceptionHandler(value =NullPointerException.class)//@ExceptionHandler 注解用来指明异常的处理类型,即如果这里指定为 NullpointerException,则数组越界异常就不会进到这个方法中来 @ResponseBody public ResultBody exceptionHandler(HttpServletRequest req, NullPointerException e){ log.error("发生空指针异常!原因是:",e); return ResultBody.error(CommonEnum.BODY_NOT_MATCH); } /** * 处理其他异常 * @param req * @param e * @return */ @ExceptionHandler(value =Exception.class) //@ExceptionHandler 注解用来指明异常的处理类型,即如果这里指定为 NullpointerException,则数组越界异常就不会进到这个方法中来 @ResponseBody public ResultBody exceptionHandler(HttpServletRequest req, Exception e){ log.error("未知异常!原因是:",e); return ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR); } }
一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰