如何在Spring Boot应用程序中记录验证错误

时间:2018-10-16 17:12:53

标签: spring spring-boot logging bean-validation hibernate-validator

我在REST服务中使用SpringBoot(spring-boot-starter-web 1.5.16.RELEASE)和hibernate-validator 6.0.11.Final。

用适当的验证约束注释的DTO对象(更新:我在控制器的参数上使用@Valid注释),并且验证按预期进行。

我希望所有(发送给客户端的)验证错误都记录在日志文件中。

我认为应该有一些简单的方法来启用这种消息(例如,在应用程序属性中标记),但我在任何地方都找不到。

任何建议将不胜感激。

3 个答案:

答案 0 :(得分:2)

更新: 在这种情况下,您可以在控制器方法中使用BindingResult bean偏斜之后定义的@Valid对象,例如

@RequestMapping(value = "/foo")
public String foo(@Valid POJO object, BindingResult result) {
   List<FieldError> errors = result.getFieldErrors();
   for (FieldError error : errors ) {
     log.error(error.getDefaultMessage());
   } 
}

或者最好将@ExceptionHandler用于异常类型MethodArgumentNotValidException


旧答案: 如果您正在验证像

这样的bean
Set<ConstraintViolation<POJO>> violations = validator.validate(pojo);

然后您可以遍历违规并将其记录下来,例如

for (ConstraintViolation<POJO> violation : violations) {
   log.error(violation.getMessage()); 
}

复制自:https://www.baeldung.com/javax-validation

答案 1 :(得分:1)

您必须使用@ControllerAdvice定义全局异常处理程序,以捕获所有与JSR 303相关的错误。 即使您在这里为自己的业务异常定义异常处理程序,并根据需要记录它们。

 @ControllerAdvice
    class ApiException{
     @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        @ResponseBody
        public ValidationErrorDTO processValidationError(MethodArgumentNotValidException ex) {
            BindingResult result = ex.getBindingResult();
            List<FieldError> fieldErrors = result.getFieldErrors();

          //log errors here

            return processFieldErrors(fieldErrors);
        }

      private ValidationErrorDTO processFieldErrors(List<FieldError> fieldErrors) {
            ValidationErrorDTO dto = new ValidationErrorDTO();

            for (FieldError fieldError: fieldErrors) {
                String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError);
                dto.addFieldError(fieldError.getField(), localizedErrorMessage);
            }

            return dto;
        }

    }

    public class ValidationErrorDTO {

        private List<FieldErrorDTO> fieldErrors = new ArrayList<>();

        public ValidationErrorDTO() {

        }

        public void addFieldError(String path, String message) {
            FieldErrorDTO error = new FieldErrorDTO(path, message);
            fieldErrors.add(error);
        }

    }

答案 2 :(得分:0)

事实证明,例如org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver确实会记录验证错误(这正是我真正需要的),例如

2018-10-18 12:54:25.552  WARN 22760 --- [nio-8092-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for 

我没有看到这些消息的原因是在日志聚合工具过滤器中(即,我在Kibana中没有看到消息,但它们出现在本地计算机上)。

对于那些不会在本地看到消息的人-检查日志配置,并确保Spring日志没有在此处静音。