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



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

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

我想将所有验证错误(发送到客户端(记录在日志文件中。

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

任何建议将不胜感激。

事实证明,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 日志没有在那里静音。

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

@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


旧答案:如果您正在验证豆类,例如

Set<ConstraintViolation<POJO>> violations = validator.validate(pojo);

然后,您可以迭代违规并记录它们,例如

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

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

您必须使用 @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);
}
}

最新更新