java异常设计_Java中如何优雅的设计异常(完整版)

导语

上一篇文章由于各种原因吧,并没有太多的说明和代码,再次跟各位读者说声抱歉。今天在补发一篇详细的说明,让大家久等了。下面我将从顶层接口一步步带大家体验一下完整的流程。

整体设计

7cd217636df4caeb89381147ada9a526.png4种异常实现

BaseException

基础异常,可通过构造函数进行扩展满足不同的需求

public class BaseException extends RuntimeException {/** * 错误编号 */ private final String code; /** * 错误编号 英文 */ private final String codeEn; /** * 关键业务单编号 */ private final String bussinessId; /** * 附加错误信息 */ private String addtionalMessage; /** * 业务异常 */ public & ErrorEnumInterface> BaseException(T errorEnum) { this(errorEnum, ""); } public & ErrorEnumInterface> BaseException(T errorEnum, String bussinessId) { this(errorEnum, bussinessId, ""); } public & ErrorEnumInterface> BaseException(T errorEnum, String bussinessId, String message) { this(errorEnum, bussinessId, message, null); } /** * 业务异常 * * @param errorEnum 业务异常枚举值 * @param bussinessId 关键业务单号 * @param cause 底层错误 * @param */ public & ErrorEnumInterface> BaseException(T errorEnum, String bussinessId, Throwable cause) { super(errorEnum.getErrorInfo().getMessage(), cause); ErrorInfo errorInfo = errorEnum.getErrorInfo(); this.code = errorInfo.getCode(); this.bussinessId = bussinessId; this.codeEn = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, errorEnum.name()); } public & ErrorEnumInterface> BaseException(T errorEnum, String bussinessId, String message, Throwable cause) { super(String.format("%s %n %s ", errorEnum.getErrorInfo().getMessage(), message), cause); ErrorInfo errorInfo = errorEnum.getErrorInfo(); this.code = errorInfo.getCode(); this.bussinessId = bussinessId; this.codeEn = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, errorEnum.name()); } /** * 自定义业务异常 * * @param message * @param errorCode * @param codeEn * @param bussinessId * @param cuase */ public BaseException(String message, String errorCode, String codeEn, String bussinessId, Throwable cuase) { super(message, cuase); this.code = errorCode; this.bussinessId = bussinessId; this.codeEn = codeEn; } @Override public String toString() { return MoreObjects.toStringHelper(this).add("message", this.getMessage()).add("code", this.code) .add("codeEn", this.codeEn).add("bussinessId", this.bussinessId) .add("addtionalMessage", this.addtionalMessage).toString(); }

}

ArgumentError

参数异常枚举类

public enum ArgumentError implements ErrorEnumInterface {/** * 10000 ,"参数异常" */ COMMON_ERROR(new ErrorInfo("01000", "参数异常")), NOT_NULL(new ErrorInfo("10100", "参数不能为空")), NOT_NULL_EPMTY(new ErrorInfo("10101", "参数不能为null和空值")); private ErrorInfo errorInfo; ArgumentError(ErrorInfo errorInfo) { this.errorInfo = errorInfo; } @Override public ErrorInfo getErrorInfo() { return null; }}

ArgumentException

参数错误异常类,其他异常的实现基本大同小异,可参照ArgumentException进行扩展

/*** 参数错误异常类 */public class ArgumentException extends BaseException { public & ErrorEnumInterface> ArgumentException(T errorEnum) { this(errorEnum, ""); } public & ErrorEnumInterface> ArgumentException(T errorEnum, String bussinessId) { this(errorEnum, bussinessId, null); } public & ErrorEnumInterface> ArgumentException(T errorEnum, String bussinessId, Throwable cause) { super(errorEnum, bussinessId, cause); } public ArgumentException(String message, String errorCode, String codeEn, String bussinessId, Throwable cuase) { super(message, errorCode, codeEn, bussinessId, cuase); }}

f67802926cd2c7a3e6d412bad7a31fbc.png全局异常处理

异常处理

9e6886ad1600e8caa2f06cef0dbc6410.png

@ControllerAdvice 是Spring3.2提供的新注解,不了解的可以去网上查一下,这里就不做过多的解释了,直接上代码

/*** 通常异常处理 */@ControllerAdvice@Slf4jpublic class ControllerExceptionhandler { private static Logger logger = LoggerFactory.getLogger(ControllerExceptionhandler.class); /** * 处理参数异常 * * @param exception * @param request * @return 标准错误400 */ @ExceptionHandler(value = ArgumentException.class) public ResponseEntity handleArgumentException(ArgumentException exception, HttpServletRequest request) { return new ResponseEntity<>(new BaseExceptionBody(exception), HttpStatus.BAD_REQUEST); } /** * 处理业务异常 * * @param exception * @param request * @return标准返回值500 */ @ExceptionHandler(value = BusinessException.class) public ResponseEntity handleBusinessException(BusinessException exception, HttpServletRequest request) { return new ResponseEntity<>(new BaseExceptionBody(exception), HttpStatus.INTERNAL_SERVER_ERROR); } /** * 处理权限异常 * * @param exception * @param request * @return 标准错误401 未授权登录, 403 没有权限 */ @ExceptionHandler(value = PermissionException.class) public ResponseEntity handlePermissionException(PermissionException exception, HttpServletRequest request) { HttpStatus status = HttpStatus.SERVICE_UNAVAILABLE; String notLogin = PermissionError.NOT_LOG_IN.getErrorInfo().getCode(); String noPermission = PermissionError.NO_Permission.getErrorInfo().getCode(); if (notLogin.equals(exception.getCode())) { status = HttpStatus.UNAUTHORIZED; } else if (noPermission.equals(exception.getCode())) { status = HttpStatus.FORBIDDEN; } return new ResponseEntity<>(new BaseExceptionBody(exception), status); } /** * 处理其他异常 * * @param exception * @param request * @return标准返回值500 */ @ExceptionHandler(value = Exception.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public ResponseEntity handleException(Exception exception, HttpServletRequest request) { logger.error(" [com.bmsoft.framework.core] Unkown Exception", exception); CommonException e = new CommonException(CommonErrors.UNKNOW_ERROR, "", exception); return new ResponseEntity<>(new BaseExceptionBody(e), HttpStatus.INTERNAL_SERVER_ERROR); } /** * 处理其他异常 * * @param t * @param request * @return标准返回值500 */ @ExceptionHandler(value = Throwable.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public ResponseEntity handleException(Throwable t, HttpServletRequest request) { logger.error(" [com.bmsoft.framework.core] Unkown Exception", t); CommonException e = new CommonException(CommonErrors.UNKNOW_ERROR, "", t); return new ResponseEntity<>(new BaseExceptionBody(e), HttpStatus.INTERNAL_SERVER_ERROR); } /** * 处理fegin 以及子类异常 * * @param exception * @param request * @return 500 */ @ExceptionHandler(value = FeignException.class) public ResponseEntity handleFiegnException(FeignException exception, HttpServletRequest request) { ObjectMapper mapper = new ObjectMapper(); String content = exception.getMessage().substring(exception.getMessage().indexOf("; content:\n") + 11); BaseExceptionBody body = null; try { body = mapper.readValue(content, BaseExceptionBody.class); } catch (IOException e) { body = new BaseExceptionBody(new CommonException(CommonErrors.UNKNOW_ERROR, "", exception)); } return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR); }}

测试案例

719bce7d655c8875f57cfa3768803b69.png

总结

代码整体来说比较通俗易懂,没有什么难点,主要都集中在统一异常处理那块。中间在各类异常的处理中构造了多种情况的处理,还引入了枚举进行统一规范。

路过朋友都看到这了就给点个赞评论一下吧,谢谢啦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值