Я использую SpringBoot (spring-boot-starter-web 1.5.16.RELEASE) и hibernate-validator 6.0.11.Final в моем сервисе REST.
Объекты DTO аннотированы правильными ограничениями проверки (ОБНОВЛЕНИЕ: я использую аннотацию @Valid для параметра контроллера), и проверка работает должным образом.
Я хотел бы, чтобы все ошибки проверки (которые были отправлены клиентам) регистрировались в файлах журнала.
Я предполагаю, что должен быть какой-то простой способ включить такие сообщения (например, флаг в свойствах приложения), но я нигде его не могу найти.
Мы ценим любые предложения.
Обновлять:
В этом случае вы можете использовать объект 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
старый ответ: Если вы проверяете beans как
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);
}
}
Оказалось, что 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 там не отключены.
для завершения: logging.level.org.springframework.web.servlet.mvc = DEBUG
Я использую аннотацию @Valid в своем контроллере