首页  编辑  

Java SpringBoot通用异常处理类

Tags: /Java/   Date Created:
Java SpringBoot通用异常处理类
适合返回合适的数据给前端AJAX API调用。

  1. package tacos.advisor;
  2. import com.fasterxml.jackson.databind.exc.InvalidFormatException;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.context.support.DefaultMessageSourceResolvable;
  6. import org.springframework.http.ResponseEntity;
  7. import org.springframework.http.converter.HttpMessageNotReadableException;
  8. import org.springframework.validation.BindException;
  9. import org.springframework.web.bind.MethodArgumentNotValidException;
  10. import org.springframework.web.bind.MissingPathVariableException;
  11. import org.springframework.web.bind.MissingServletRequestParameterException;
  12. import org.springframework.web.bind.annotation.ExceptionHandler;
  13. import org.springframework.web.bind.annotation.RestControllerAdvice;
  14. import tacos.model.APIResult;
  15. import javax.validation.ConstraintViolation;
  16. import javax.validation.ConstraintViolationException;
  17. import java.util.Optional;
  18. import java.util.regex.Matcher;
  19. import java.util.regex.Pattern;
  20. import java.util.stream.Collectors;
  21. @RestControllerAdvice
  22. @SuppressWarnings("unused")
  23. public class GlobalExceptionHandler {
  24.     private ResponseEntity<APIResult<Object>> logObject(int code, String msg, String category) {
  25.         Logger log = LoggerFactory.getLogger(category);
  26.         log.error("fail: {}", msg);
  27.         return ResponseEntity.ok().body(APIResult.fail(code, msg));
  28.     }
  29.     @ExceptionHandler(Exception.class)
  30.     public ResponseEntity<APIResult<Object>> handleException(Throwable exception{
  31.         Logger log = LoggerFactory.getLogger(exception.getStackTrace()[0].getClassName());
  32.         log.error("fail: {}""", exception);
  33.         return ResponseEntity.ok().body(APIResult.unknown(exception.getMessage()));
  34.     }
  35.     @ExceptionHandler(MethodArgumentNotValidException.class)
  36.     public ResponseEntity<APIResult<Object>> handleMethodArgumentNotValidException(
  37.             MethodArgumentNotValidException exception{
  38.         String msg = Optional.of(exception.getBindingResult().getFieldErrors().stream()
  39.                 .map(DefaultMessageSourceResolvable::getDefaultMessage)
  40.                 .collect(Collectors.joining("\r\n"))).orElse("Validate failed");
  41.         return logObject(APIResult.ERROR_PARAM, msg, exception.getStackTrace()[0].getClassName());
  42.     }
  43.     @ExceptionHandler(MissingPathVariableException.class)
  44.     public ResponseEntity<APIResult<Object>> handleMissingPathVariableException(MissingPathVariableException exception{
  45.         String msg = String.format("The %s is required", exception.getVariableName());
  46.         return logObject(APIResult.ERROR_PARAM, msg, exception.getStackTrace()[0].getClassName());
  47.     }
  48.     @ExceptionHandler(MissingServletRequestParameterException.class)
  49.     public ResponseEntity<APIResult<Object>> handleMissingServletRequestParameterException(
  50.             MissingServletRequestParameterException exception{
  51.         String msg = String.format("The %s is required", exception.getParameterName());
  52.         return logObject(APIResult.ERROR_PARAM, msg, exception.getStackTrace()[0].getClassName());
  53.     }
  54.     @ExceptionHandler(ConstraintViolationException.class)
  55.     public ResponseEntity<APIResult<Object>> handleConstraintViolationException(ConstraintViolationException exception{
  56.         String msg = Optional.of(exception.getConstraintViolations().stream()
  57.                 .map(ConstraintViolation::getMessage)
  58.                 .collect(Collectors.joining("\r\n"))).orElse("Validate failed");
  59.         return logObject(APIResult.ERROR_PARAM, msg, exception.getStackTrace()[0].getClassName());
  60.     }
  61.     private static final Pattern ENUM_MSG = Pattern.compile("values accepted for Enum class: \\[(.*?)\\];(.*)from String \\\"(.*)\\\": (.*)\\n(.*)\\[\\\"(.*)\\\"\\]\\)"Pattern.MULTILINE);
  62.     @ExceptionHandler(HttpMessageNotReadableException.class)
  63.     public ResponseEntity<APIResult<Object>> handleHttpMessageNotReadableException(HttpMessageNotReadableException exception{
  64.         if (exception.getCause() != null && exception.getCause() instanceof InvalidFormatException) {
  65.             Matcher match = ENUM_MSG.matcher(exception.getMessage());
  66.             if (match.find()) {
  67.                 return logObject(APIResult.ERROR_PARAM,
  68.                         String.format("%s: Invalid value '%s', possible values - [%s]", match.group(6), match.group(3), match.group(1)),
  69.                         exception.getStackTrace()[0].getClassName());
  70.             }
  71.         }
  72.         return logObject(APIResult.ERROR_UNKNOWN, exception.getMessage(), exception.getStackTrace()[0].getClassName());
  73.     }
  74.     @ExceptionHandler(BindException.class)
  75.     public ResponseEntity<APIResult<Object>> handleBindException(BindException exception{
  76.         String msg = Optional.of(exception.getBindingResult().getFieldErrors().stream().map(e -> e.getField() + ": " + e.getDefaultMessage())
  77.                 .collect(Collectors.joining("\r\n"))).orElse("Validate failed");
  78.         return logObject(APIResult.ERROR_PARAM, msg, exception.getStackTrace()[0].getClassName());
  79.     }
  80. }