Springboot全局异常处理

//错误异常响应类
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class ErrorResponse {
    private int code;
    private String message;
}

 

//基础异常类

import com.web.enums.IResponseEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class BaseException extends Exception {
    private int code;
    private String message;
    private IResponseEnum iResponseEnum;
    private Throwable cause;
    private Object[] args;

    public BaseException(int code , String message){
        super(message);
        this.code = code;
        this.message = message;
    }
    public BaseException(IResponseEnum iResponseEnum){
        this.iResponseEnum = iResponseEnum;
    }
    public BaseException(IResponseEnum iResponseEnum,Object[] args , String message){
        this.iResponseEnum = iResponseEnum;
        this.args = args;
        this.message = message;
    }
    public BaseException(IResponseEnum iResponseEnum,Object[] args , String message,Throwable cause){
        this.iResponseEnum = iResponseEnum;
        this.args = args;
        this.message = message;
        this.cause = cause;
    }

}
//异常接口类
package com.web.enums;

public interface IResponseEnum {
      int getCode();
      String getMessage();
}

 

//全局异常处理类


import com.web.enums.ArgumentResponseEnum;
import com.web.enums.CommonResponseEnum;
import com.web.enums.ServletResponseEnum;
import com.web.exceptions.BaseException;
import com.web.exceptions.BusinessException;
import com.web.messages.UnifiedMessageSource;
import com.web.response.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;

@Slf4j
@RestControllerAdvice
public class UnifiedExceptionHandler {
    private static final String ENV_PROD = "prod";
    @Autowired
    private UnifiedMessageSource unifiedMessageSource;
    @Value("${spring.profiles.active}")
    private String profile;

    public String getMessage(BaseException e) {
        String code = "response." + e.getIResponseEnum().toString();
        String message = unifiedMessageSource.getMessage(code, e.getArgs());
        if (StringUtils.isBlank(message) || message.isEmpty()) {
            return e.getMessage();
        }
        return message;
    }

    @ExceptionHandler(value = BusinessException.class)
    @ResponseBody
    public ErrorResponse handleBusinessException(BaseException e) {
        log.error(e.getMessage(), e);
        return new ErrorResponse(e.getIResponseEnum().getCode(), getMessage(e));
    }

    @ExceptionHandler({
            NoHandlerFoundException.class, HttpRequestMethodNotSupportedException.class,
            HttpMediaTypeNotSupportedException.class, MissingPathVariableException.class,
            MissingServletRequestParameterException.class, TypeMismatchException.class,
            HttpMessageNotReadableException.class, HttpMessageNotWritableException.class,
            HttpMediaTypeNotAcceptableException.class, ServletRequestBindingException.class,
            ConversionNotSupportedException.class, MissingServletRequestPartException.class,
            AsyncRequestTimeoutException.class
    })
    @ResponseBody
    public ErrorResponse handleServletException(Exception e) {
        log.error(e.getMessage(), e);
        int code = CommonResponseEnum.SERVER_ERROR.getCode();
        try {
            ServletResponseEnum servletResponseEnum = ServletResponseEnum.valueOf(e.getClass().getSimpleName());
            code = servletResponseEnum.getCode();
        } catch (IllegalArgumentException ex) {
            log.error("class [{}] not defined in enum {}", e.getClass().getName(), ServletResponseEnum.class.getName());
        }
        if (ENV_PROD.equals(profile)) {
            // 当为生产环境, 不适合把具体的异常信息展示给用户, 比如404.
            code = CommonResponseEnum.SERVER_ERROR.getCode();
            BaseException baseException = new BaseException(CommonResponseEnum.SERVER_ERROR);
            String message = getMessage(baseException);
            return new ErrorResponse(code, message);
        }
        return new ErrorResponse(code, e.getMessage());
    }

    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ErrorResponse handleBindException(BindException e){
        log.error("Parameters error",e);
        return wrapperBindingResponse(e.getBindingResult());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ErrorResponse handleValidException(MethodArgumentNotValidException e) {
        log.error("data parameter validation problem {},invalid type {}",e.getMessage(),e.getClass());
        return wrapperBindingResponse(e.getBindingResult());
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ErrorResponse handleException(Exception e) {
        log.error(e.getMessage(), e);
        if (ENV_PROD.equals(profile)) {
            // 当为生产环境, 不适合把具体的异常信息展示给用户, 比如数据库异常信息.
            int code = CommonResponseEnum.SERVER_ERROR.getCode();
            BaseException baseException = new BaseException(CommonResponseEnum.SERVER_ERROR);
            String message = getMessage(baseException);
            return new ErrorResponse(code, message);
        }
        return new ErrorResponse(CommonResponseEnum.SERVER_ERROR.getCode(), e.getMessage());
    }

    private ErrorResponse wrapperBindingResponse(BindingResult bindingResult) {
        StringBuilder msg = new StringBuilder();
        bindingResult.getFieldErrors().forEach(item->{
            if (item instanceof FieldError) {
                msg.append(item.getField()).append(":");
            }
            msg.append(item.getDefaultMessage() == null ? "" : item.getDefaultMessage());
            msg.append(";");
        });
        return new ErrorResponse(ArgumentResponseEnum.VALID_ERROR.getCode(), msg.toString().substring(0,msg.length()-1));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路飞海米

一起加油哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值