Включить имя поля внутри сообщения об ошибке с помощью Hibernate Validator

Я использую Hibernate Validator 4.2.0.Final и ищу самый простой способ включить имя поля класса в свое сообщение об ошибке.

Я нашел следующую ветку Использование собственного ResourceBundle с Hibernate Validator. В соответствии с этим я должен создать свою пользовательскую аннотацию для каждой аннотации ограничения, добавив одно свойство к каждому.

Есть ли более чистый способ добиться этого?

Следующий код:

@Size(max = 5)
private String myField;

выдает ошибку по умолчанию: размер должен быть от 0 до 5.

Я хотел бы, чтобы это было: размер myField должен быть между 0 и 5.

Ответ 1

Для всех тех, кто ищет способ доступа к классу внутри вашего валидатора. Добавление аннотации hibernate на уровне класса вместо переменного уровня дает вам доступ к объекту класса (при условии, что вы определили пользовательский валидатор).

public class myCustomValidator implements ContraintValidator <MyAnnotation, MyAnnotatedClass> {

    public void initialize (...){ ... };

    public boolean isValid (MyAnnotatedClass myAnnotatedClass) {

        // access to elements of your myAnnotatedClass

    }
} 

Ответ 2

Вы можете получить имя поля с помощью метода getPropertyPath() из ConstraintViolation class.

Хорошим сообщением об ошибке по умолчанию может быть:

violation.getPropertyPath() + " " + violation.getMessage();

Что даст вам "foo может не быть нулевым", или "foo.bar может не быть пустым" в случае вложенных объектов.

Ответ 3

Я не знаю какого-либо общего способа, но вы можете определить собственное сообщение об ошибке и включить в него имя поля.

@Size(max = 5, message = "myField size must be between 0 and 5")  
private String myField;

Ответ 4

Я помещаю каждое сообщение проверки поля в файл свойств, например:

field.student.name.size.message = Student name size is not valid.

и в bean, используйте его следующим образом:

@Size(max = 5, message = "${field.student.name.size.message}")  
private String myField;

Я знаю, что это не идеальное решение, но я также не нашел лучшего способа.

Ответ 5

Если ваши сообщения находятся в файле .properties, тогда нет переменной интерполяции для доступа к имени свойства, но вы можете добиться этого одним из способов:

//in ValidationMessages.properties
app.validation.size.msg=size must be between {min} and {max}

@Size(min=10, max=15, message = "myField {app.validation.size.msg})
private String myField;

ИЛИ

//in ValidationMessages.properties
app.validation.size.msg=size must be between {min} and {max} but provided ${validatedValue}

@Size(min=10, max=15, message = "myField {app.validation.size.msg})
private String myField;

Ссылка: интерполяция сообщения

Ответ 6

используйте oval, у этого есть большое количество аннотаций и возможные способы отображения сообщений.

Ответ 7

используйте этот метод (например, экземпляр ConstraintViolationException):

Set<ConstraintViolation<?>> set =  ex.getConstraintViolations();
List<ErrorField> errorFields = new ArrayList<>(set.size());
ErrorField field = null;
for (Iterator<ConstraintViolation<?>> iterator = set.iterator();iterator.hasNext(); ) {
    ConstraintViolation<?> next =  iterator.next();
   System.out.println(((PathImpl)next.getPropertyPath())
            .getLeafNode().getName() + "  " +next.getMessage());


}