GlobalExceptionHandler.java 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package com.poyee.exception;
  2. import com.poyee.res.Result;
  3. import com.poyee.utils.I18nUtil;
  4. import com.poyee.utils.ServletUtils;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.validation.ObjectError;
  7. import org.springframework.web.bind.MethodArgumentNotValidException;
  8. import org.springframework.web.bind.annotation.ExceptionHandler;
  9. import org.springframework.web.bind.annotation.RestControllerAdvice;
  10. import com.auth0.jwt.exceptions.JWTVerificationException;
  11. import com.auth0.jwt.exceptions.TokenExpiredException;
  12. import org.springframework.http.converter.HttpMessageNotReadableException;
  13. import org.springframework.web.HttpMediaTypeNotSupportedException;
  14. import org.springframework.web.HttpRequestMethodNotSupportedException;
  15. import org.springframework.web.bind.MissingServletRequestParameterException;
  16. import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
  17. import javax.servlet.http.HttpServletRequest;
  18. import javax.servlet.http.HttpServletResponse;
  19. import java.util.List;
  20. import java.util.stream.Collectors;
  21. /**
  22. * 全局异常处理器
  23. */
  24. @Slf4j
  25. @RestControllerAdvice
  26. public class GlobalExceptionHandler {
  27. /**
  28. * 处理业务异常
  29. */
  30. @ExceptionHandler(BusinessException.class)
  31. public Result<Void> handleBusinessException(BusinessException e) {
  32. log.warn("业务异常:{}", I18nUtil.getMessage(e.getMessage()));
  33. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  34. return Result.error(e.getCode(), I18nUtil.getMessage(e.getMessage()));
  35. }
  36. @ExceptionHandler(RuntimeException.class)
  37. public Result<Void> handleRuntimeException(RuntimeException e) {
  38. log.warn("运行异常:{}", I18nUtil.getMessage(e.getMessage()));
  39. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  40. return Result.error(I18nUtil.getMessage(e.getMessage()));
  41. }
  42. /**
  43. * 处理其他异常
  44. */
  45. @ExceptionHandler(Exception.class)
  46. public Result<Void> handleException(Exception e) {
  47. log.error("系统异常", e);
  48. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  49. return Result.error(500, "系统繁忙,请稍后重试");
  50. }
  51. /**
  52. * 处理其他异常
  53. */
  54. @ExceptionHandler(IllegalArgumentException.class)
  55. public Result<Void> handleIllegalArgumentException(IllegalArgumentException e) {
  56. log.error("参数异常", e);
  57. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_BAD_REQUEST);
  58. return Result.error(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
  59. }
  60. /**
  61. * 参数错误
  62. */
  63. @ExceptionHandler(value = MethodArgumentNotValidException.class)
  64. public Result<Void> methodArgumentNotValidExceptionHandle(MethodArgumentNotValidException ex, HttpServletRequest request) {
  65. log.error("Unhandled RequestParamException from URL [{}]", request.getRequestURI(), ex);
  66. List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
  67. List<String> collect = allErrors.stream()
  68. .map(error -> {
  69. String defaultMessage = error.getDefaultMessage();
  70. String i18nMessage = I18nUtil.getMessage(defaultMessage);
  71. return i18nMessage != null ? i18nMessage : defaultMessage;
  72. })
  73. .collect(Collectors.toList());
  74. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_BAD_REQUEST);
  75. return Result.error(HttpServletResponse.SC_BAD_REQUEST, collect.toString());
  76. }
  77. /**
  78. * 缺少请求参数
  79. */
  80. @ExceptionHandler(MissingServletRequestParameterException.class)
  81. public Result<Void> handleMissingServletRequestParameter(MissingServletRequestParameterException e) {
  82. log.warn("缺少请求参数:{}", e.getParameterName());
  83. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_BAD_REQUEST);
  84. return Result.error(HttpServletResponse.SC_BAD_REQUEST, "缺少请求参数:" + e.getParameterName());
  85. }
  86. /**
  87. * 参数类型不匹配
  88. */
  89. @ExceptionHandler(MethodArgumentTypeMismatchException.class)
  90. public Result<Void> handleMethodArgumentTypeMismatch(MethodArgumentTypeMismatchException e) {
  91. log.warn("参数类型不匹配:{}", e.getName());
  92. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_BAD_REQUEST);
  93. return Result.error(HttpServletResponse.SC_BAD_REQUEST, "参数类型不匹配:" + e.getName());
  94. }
  95. /**
  96. * 请求体不可读(JSON格式错误等)
  97. */
  98. @ExceptionHandler(HttpMessageNotReadableException.class)
  99. public Result<Void> handleHttpMessageNotReadable(HttpMessageNotReadableException e) {
  100. log.warn("请求体解析失败:{}", e.getMessage());
  101. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_BAD_REQUEST);
  102. return Result.error(HttpServletResponse.SC_BAD_REQUEST, "请求体格式错误");
  103. }
  104. /**
  105. * 请求方法不支持
  106. */
  107. @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
  108. public Result<Void> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e) {
  109. log.warn("请求方法不支持:{}", e.getMethod());
  110. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
  111. return Result.error(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "不支持的请求方法:" + e.getMethod());
  112. }
  113. /**
  114. * 媒体类型不支持
  115. */
  116. @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
  117. public Result<Void> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException e) {
  118. log.warn("媒体类型不支持:{}", e.getContentType());
  119. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
  120. return Result.error(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "不支持的媒体类型:" + e.getContentType());
  121. }
  122. /**
  123. * JWT Token 过期
  124. */
  125. @ExceptionHandler(TokenExpiredException.class)
  126. public Result<Void> handleTokenExpired(TokenExpiredException e) {
  127. log.warn("Token已过期:{}", e.getMessage());
  128. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  129. return Result.error(HttpServletResponse.SC_UNAUTHORIZED, "Token已过期,请重新登录");
  130. }
  131. /**
  132. * JWT Token 验证失败
  133. */
  134. @ExceptionHandler(JWTVerificationException.class)
  135. public Result<Void> handleJWTVerification(JWTVerificationException e) {
  136. log.warn("Token验证失败:{}", e.getMessage());
  137. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  138. return Result.error(HttpServletResponse.SC_UNAUTHORIZED, "Token无效,请重新登录");
  139. }
  140. /**
  141. * 空指针异常
  142. */
  143. @ExceptionHandler(NullPointerException.class)
  144. public Result<Void> handleNullPointerException(NullPointerException e) {
  145. log.error("空指针异常", e);
  146. ServletUtils.getHttpResponse().setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  147. return Result.error(500, "系统繁忙,请稍后重试");
  148. }
  149. }