加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

spring boot教程之全局处理异常封装

发布时间:2020-05-24 00:23:20 所属栏目:Java 来源:互联网
导读:spring boot教程之全局处理异常封装 1|1简介 在项目中经常出现系统异常的情况,比如NullPointerException等等.如果默认未处理的情况下,springboot会响应默认的错误提示,这样对用户体验不是友好,系统层面的错误,用户不能感知到,即使为500的错误,可以给用户提示

1|1简介

在项目中经常出现系统异常的情况,比如NullPointerException等等。如果默认未处理的情况下,springboot会响应默认的错误提示,这样对用户体验不是友好,系统层面的错误,用户不能感知到,即使为500的错误,可以给用户提示一个类似服务器开小差的友好提示等。

在微服务里,每个服务中都会有异常情况,几乎所有服务的默认异常处理配置一致,导致很多重复编码,我们将这些重复默认异常处理可以抽出一个公共starter包,各个服务依赖即可,定制化异常处理在各个模块里开发。

1|2配置

unified-dispose-springboot-starter

这个模块里包含异常处理以及全局返回封装等功能,下面。

完整目录结构如下:

├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── purgetiem
│   │   │           └── starter
│   │   │               └── dispose
│   │   │                   ├── GlobalDefaultConfiguration.java
│   │   │                   ├── GlobalDefaultProperties.java
│   │   │                   ├── Interceptors.java
│   │   │                   ├── Result.java
│   │   │                   ├── advice
│   │   │                   │   └── CommonResponseDataAdvice.java
│   │   │                   ├── annotation
│   │   │                   │   ├── EnableGlobalDispose.java
│   │   │                   │   └── IgnorReponseAdvice.java
│   │   │                   └── exception
│   │   │                       ├── GlobalDefaultExceptionHandler.java
│   │   │                       ├── category
│   │   │                       │   └── BusinessException.java
│   │   │                       └── error
│   │   │                           ├── CommonErrorCode.java
│   │   │                           └── details
│   │   │                               └── BusinessErrorCode.java
│   │   └── resources
│   │       ├── META-INF
│   │       │   └── spring.factories
│   │       └── dispose.properties
│   └── test
│       └── java

异常处理

@RestControllerAdvice 或者 @ControllerAdvice为spring的异常处理注解。

我们先创建GlobalDefaultExceptionHandler 全局异常处理类:

@RestControllerAdvice
public class GlobalDefaultExceptionHandler {

 private static final Logger log = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class);

 /**
 * NoHandlerFoundException 404 异常处理
 */
 @ExceptionHandler(value = NoHandlerFoundException.class)
 @ResponseStatus(HttpStatus.NOT_FOUND)
 public Result handlerNoHandlerFoundException(NoHandlerFoundException exception) {
 outPutErrorWarn(NoHandlerFoundException.class,CommonErrorCode.NOT_FOUND,exception);
 return Result.ofFail(CommonErrorCode.NOT_FOUND);
 }

 /**
 * HttpRequestMethodNotSupportedException 405 异常处理
 */
 @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
 public Result handlerHttpRequestMethodNotSupportedException(
  HttpRequestMethodNotSupportedException exception) {
 outPutErrorWarn(HttpRequestMethodNotSupportedException.class,CommonErrorCode.METHOD_NOT_ALLOWED,exception);
 return Result.ofFail(CommonErrorCode.METHOD_NOT_ALLOWED);
 }

 /**
 * HttpMediaTypeNotSupportedException 415 异常处理
 */
 @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
 public Result handlerHttpMediaTypeNotSupportedException(
  HttpMediaTypeNotSupportedException exception) {
 outPutErrorWarn(HttpMediaTypeNotSupportedException.class,CommonErrorCode.UNSUPPORTED_MEDIA_TYPE,exception);
 return Result.ofFail(CommonErrorCode.UNSUPPORTED_MEDIA_TYPE);
 }

 /**
 * Exception 类捕获 500 异常处理
 */
 @ExceptionHandler(value = Exception.class)
 public Result handlerException(Exception e) {
 return ifDepthExceptionType(e);
 }

 /**
 * 二次深度检查错误类型
 */
 private Result ifDepthExceptionType(Throwable throwable) {
 Throwable cause = throwable.getCause();
 if (cause instanceof ClientException) {
  return handlerClientException((ClientException) cause);
 }
 if (cause instanceof FeignException) {
  return handlerFeignException((FeignException) cause);
 }
 outPutError(Exception.class,CommonErrorCode.EXCEPTION,throwable);
 return Result.ofFail(CommonErrorCode.EXCEPTION);
 }

 /**
 * FeignException 类捕获
 */
 @ExceptionHandler(value = FeignException.class)
 public Result handlerFeignException(FeignException e) {
 outPutError(FeignException.class,CommonErrorCode.RPC_ERROR,e);
 return Result.ofFail(CommonErrorCode.RPC_ERROR);
 }

 /**
 * ClientException 类捕获
 */
 @ExceptionHandler(value = ClientException.class)
 public Result handlerClientException(ClientException e) {
 outPutError(ClientException.class,e);
 return Result.ofFail(CommonErrorCode.RPC_ERROR);
 }

 /**
 * BusinessException 类捕获
 */
 @ExceptionHandler(value = BusinessException.class)
 public Result handlerBusinessException(BusinessException e) {
 outPutError(BusinessException.class,CommonErrorCode.BUSINESS_ERROR,e);
 return Result.ofFail(e.getCode(),e.getMessage());
 }

 /**
 * HttpMessageNotReadableException 参数错误异常
 */
 @ExceptionHandler(HttpMessageNotReadableException.class)
 public Result handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
 outPutError(HttpMessageNotReadableException.class,CommonErrorCode.PARAM_ERROR,e);
 String msg = String.format("%s : 错误详情( %s )",CommonErrorCode.PARAM_ERROR.getMessage(),e.getRootCause().getMessage());
 return Result.ofFail(CommonErrorCode.PARAM_ERROR.getCode(),msg);
 }

 /**
 * BindException 参数错误异常
 */
 @ExceptionHandler(BindException.class)
 public Result handleMethodArgumentNotValidException(BindException e) {
 outPutError(BindException.class,e);
 BindingResult bindingResult = e.getBindingResult();
 return getBindResultDTO(bindingResult);
 }

 private Result getBindResultDTO(BindingResult bindingResult) {
 List<FieldError> fieldErrors = bindingResult.getFieldErrors();
 if (log.isDebugEnabled()) {
  for (FieldError error : fieldErrors) {
  log.error("{} -> {}",error.getDefaultMessage(),error.getDefaultMessage());
  }
 }

 if (fieldErrors.isEmpty()) {
  log.error("validExceptionHandler error fieldErrors is empty");
  Result.ofFail(CommonErrorCode.BUSINESS_ERROR.getCode(),"");
 }

 return Result
  .ofFail(CommonErrorCode.PARAM_ERROR.getCode(),fieldErrors.get(0).getDefaultMessage());
 }

 public void outPutError(Class errorType,Enum secondaryErrorType,Throwable throwable) {
 log.error("[{}] {}: {}",errorType.getSimpleName(),secondaryErrorType,throwable.getMessage(),throwable);
 }

 public void outPutErrorWarn(Class errorType,Throwable throwable) {
 log.warn("[{}] {}: {}",throwable.getMessage());
 }

}

大致内容处理了一些项目常见的异常Exception,BindException参数异常等。

这里将默认的404、405、415等默认http状态码也重写了。

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读