如何记录 SpringBoot 请求验证错误?

huangapple go评论67阅读模式
英文:

How to log SpringBoot request validation errors?

问题

@GetMapping(value = "/hello", produces = MediaType.APPLICATION_JSON_VALUE)
public String sayHi(@RequestParam(name = "size") @Max(30) Integer size) {
    return "Hi" + size.toString();
}

如果 size 的值大于 30,则该 API 会返回一个验证错误。但是,除此之外,我还想找一种记录这种无效请求的方法。

英文:

How to log request validation errors in springboot? Say, we have an API like below and I need to log if there's a validation error in one of the request params?

@GetMapping(value = "/hello", produces = MediaType.APPLICATION_JSON_VALUE)
    public String sayHi(@RequestParam(name = "size") @Max(30) Integer size) {
      return "Hi" + size.toString();
}

If the size value is more than 30 then the API returns a validation error. But, along with that, I'm also looking for a way to log such invalid requests

答案1

得分: 0

由于您正在使用 Spring Boot您可以使用 `@ControllerAdvice` 来实现 Spring Boot 的异常处理集中化以便记录这些错误或返回自定义的通用响应类。`@ControllerAdvice` 注解将使其在全局范围内适用于所有控制器

为了捕获请求体的验证错误我们将处理 `MethodArgumentNotValidExceptions`,如下所示

@ControllerAdvice
class ErrorHandlingControllerAdvice {

  private static final Logger LOGGER = LoggerFactory.getLogger(ErrorHandlingControllerAdvice.class);
  
  @ExceptionHandler(ConstraintViolationException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ResponseBody
  ApiErrorResponse onConstraintValidationException(
      ConstraintViolationException e) {
    ApiErrorResponse apiErrorResponse = new ApiErrorResponse();
    for (ConstraintViolation violation : e.getConstraintViolations()) {
      apiErrorResponse.getViolations().add(
        new Violation(violation.getPropertyPath().toString(), violation.getMessage()));
    }
    return apiErrorResponse;
  }
  
  @ExceptionHandler(MethodArgumentNotValidException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ResponseBody
  ApiErrorResponse onMethodArgumentNotValidException(
      MethodArgumentNotValidException e) {
    ApiErrorResponse error = new ApiErrorResponse();
    for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
      error.getViolations().add(
        new Violation(fieldError.getField(), fieldError.getDefaultMessage()));
    }
    LOGGER.error("在这里记录您想要的日志信息");
    return error;
  }
}
英文:

Since you are using springboot , you could use spring boot centralized exception handling using @ControllerAdvice to log these errors or return a custom common response class . The @ControllerAdvice annotation will make it apply globally to all controllers.
In order to catch validation errors for request bodies , we will handle MethodArgumentNotValidExceptions like:

@ControllerAdvice
class ErrorHandlingControllerAdvice {

  private static final Logger LOGGER = LoggerFactory.getLogger(ErrorHandlingControllerAdvice.class);
  @ExceptionHandler(ConstraintViolationException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ResponseBody
  ApiErrorResponse onConstraintValidationException(
      ConstraintViolationException e) {
    ApiErrorResponse apiErrorResponse = new ApiErrorResponse();
    for (ConstraintViolation violation : e.getConstraintViolations()) {
      apiErrorResponse.getViolations().add(
        new Violation(violation.getPropertyPath().toString(), violation.getMessage()));
    }
    return apiErrorResponse;
  }

  @ExceptionHandler(MethodArgumentNotValidException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ResponseBody
  ApiErrorResponse onMethodArgumentNotValidException(
      MethodArgumentNotValidException e) {
    ApiErrorResponse error = new ApiErrorResponse();
    for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
      error.getViolations().add(
        new Violation(fieldError.getField(), fieldError.getDefaultMessage()));
    }
    LOGGER.error("Log whatever you want to here");
    return error;
  }

}

huangapple
  • 本文由 发表于 2020年10月20日 14:55:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/64439943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定