content: package org.superboot.global.handler;
  
  import com.alibaba.fastjson.JSON;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.MessageSource;
  import org.springframework.context.i18n.LocaleContextHolder;
  import org.springframework.http.HttpStatus;
  import org.springframework.http.converter.HttpMessageNotReadableException;
  import org.springframework.validation.FieldError;
  import org.springframework.web.HttpMediaTypeNotSupportedException;
  import org.springframework.web.HttpRequestMethodNotSupportedException;
  import org.springframework.web.bind.MethodArgumentNotValidException;
  import org.springframework.web.bind.annotation.ControllerAdvice;
  import org.springframework.web.bind.annotation.ExceptionHandler;
  import org.springframework.web.bind.annotation.ResponseBody;
  import org.springframework.web.bind.annotation.ResponseStatus;
  import org.superboot.base.BaseConstants;
  import org.superboot.base.BaseException;
  import org.superboot.base.BaseMessage;
  import org.superboot.base.StatusCode;
  import org.superboot.common.pub.Pub_Tools;
  import org.superboot.common.pub.Pub_WebUtils;
  
  import javax.annotation.Resource;
  import javax.crypto.BadPaddingException;
  import javax.servlet.http.HttpServletRequest;
  import java.io.IOException;
  import java.lang.reflect.UndeclaredThrowableException;
  import java.sql.SQLException;
  import java.util.List;
  import java.util.Locale;
  
  /**
   * <b> 统一异常处理 </b>
   * <p>
   * 功能描述:处理逻辑异常造成的错误
   * </p>
   */
  @ControllerAdvice
  public class GlobalExceptionHandler {
  
  
      @Resource
      private Pub_Tools pubTools;
  
      @Autowired
      private MessageSource messageSource;
  
      @Autowired
      private Pub_WebUtils webUtils;
  
      /**
       * 默认异常处理
       *
       * @param req 请求内容
       * @param e   异常信息
       * @return
       * @throws Exception
       */
      @ExceptionHandler(value = Exception.class)
      @ResponseBody
      public BaseMessage defaultErrorHandler(HttpServletRequest req, Exception e) throws IOException {
          webUtils.saveErrLog(req, e);
          if (e.getCause() instanceof BaseException) {
              int code = ((BaseException) e).getCode();
              return pubTools.genNoMsg(code);
          }
          return pubTools.genNoMsg(StatusCode.EXCEPTION.getCode(), e.getMessage());
      }
  
      /**
       * SQL异常
       *
       * @param req
       * @param e
       * @return
       * @throws IOException
       */
      @ExceptionHandler(value = SQLException.class)
      public BaseMessage sqlExceptionHandler(HttpServletRequest req, RuntimeException e) throws IOException {
          //记录程序异常日志
          webUtils.saveErrLog(req, e);
          return pubTools.genNoMsg(StatusCode.EXCEPTION.getCode(), e.getMessage());
      }
  
      /**
       * 默认运行异常处理
       *
       * @param req 请求内容
       * @param e   异常信息
       * @return
       * @throws Exception
       */
      @ExceptionHandler(value = RuntimeException.class)
      @ResponseBody
      public BaseMessage runtimeErrorHandler(HttpServletRequest req, RuntimeException e) throws IOException {
          //记录程序异常日志
          webUtils.saveErrLog(req, e);
          return pubTools.genNoMsg(StatusCode.EXCEPTION.getCode(), e.getMessage());
      }
  
  
      /**
       * 使用反射或者代理造成的异常需要根据异常类型单独处理
       *
       * @param req 请求内容
       * @param e   异常信息
       * @return
       * @throws IOException
       */
      @ExceptionHandler(value = UndeclaredThrowableException.class)
      @ResponseBody
      public BaseMessage undeclaredThrowableException(HttpServletRequest req, UndeclaredThrowableException e) throws IOException {
          //记录程序异常日志
          webUtils.saveErrLog(req, e);
          //密文解密失败异常
          if (e.getCause() instanceof BadPaddingException) {
              return pubTools.genNoMsg(StatusCode.DECODE_FAIL.getCode(), e.getMessage());
          }
          return pubTools.genNoMsg(StatusCode.EXCEPTION.getCode(), e.getMessage());
      }
  
  
      /**
       * 字段验证异常处理,统一处理增加国际化支持
       *
       * @param req 请求内容
       * @param e   异常信息
       * @return
       * @throws Exception
       */
      @ExceptionHandler(value = MethodArgumentNotValidException.class)
      @ResponseBody
      public BaseMessage methodArgumentNotValidExceptionErrorHandler(HttpServletRequest req, Exception e) {
          MethodArgumentNotValidException c = (MethodArgumentNotValidException) e;
          List<FieldError> errors = c.getBindingResult().getFieldErrors();
          Locale locale = LocaleContextHolder.getLocale();
          StringBuffer errorMsg = new StringBuffer();
          for (FieldError err : errors) {
              String message = messageSource.getMessage(err, locale);
              errorMsg.append(err.getField() + ":" + message + ",");
          }
  
          return pubTools.genNoMsg(StatusCode.PARAMS_NOT_VALIDATE, errorMsg.subSequence(0, errorMsg.length() - 1).toString());
      }
  
  
      /**
       * 自定义异常处理
       *
       * @param req 请求内容
       * @param e   异常信息
       * @return
       * @throws Exception
       */
      @ExceptionHandler(value = BaseException.class)
      @ResponseBody
      public BaseMessage baseErrorHandler(HttpServletRequest req, Exception e) throws IOException {
          int code = ((BaseException) e).getCode();
          //记录程序异常日志
          if (StatusCode.EXCEPTION.getCode() == code) {
              webUtils.saveErrLog(req, e);
          } else {
              webUtils.saveLog(req, JSON.toJSONString(pubTools.genNoMsg(code)), req.getHeader(BaseConstants.GLOBAL_KEY.toLowerCase()), null, 0);
          }
          return pubTools.genNoMsg(code, e.getMessage());
      }
  
  
      /**
       * 参数解析异常
       *
       * @param e 异常信息
       * @return
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(HttpMessageNotReadableException.class)
      public BaseMessage handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
          return pubTools.genNoMsg(StatusCode.BAD_REQUEST, e.getMessage());
      }
  
      /**
       * 不支持当前请求方法
       *
       * @param e 异常信息
       * @return
       */
      @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
      @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
      public BaseMessage handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
          return pubTools.genNoMsg(StatusCode.METHOD_NOT_ALLOWED, e.getMessage());
      }
  
      /**
       * 不支持当前媒体类型
       *
       * @param e 异常信息
       * @return
       */
      @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
      @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
      public BaseMessage handleHttpMediaTypeNotSupportedException(Exception e) {
          return pubTools.genNoMsg(StatusCode.UNSUPPORTED_MEDIA_TYPE, e.getMessage());
      }
  
  
  }
  