使用Hibernate Validator在错误消息中包含字段名称

时间:2012-07-11 11:14:45

标签: java spring hibernate hibernate-validator

我正在使用Hibernate Validator 4.2.0.Final,我正在寻找在我的错误消息中包含类字段名称的最简单方法。

我发现的是以下帖子Using a custom ResourceBundle with Hibernate Validator。根据这个,我应该为每个约束注释创建我的自定义注释,为每个约束注释添加一个属性。

有没有更清洁的方法来实现这一目标?

以下代码:

@Size(max = 5)
private String myField;

产生默认错误:大小必须介于0和5之间。

我希望它是: myField大小必须介于0和5之间。

提前致谢。

9 个答案:

答案 0 :(得分:21)

您可以使用ConstraintViolation class中的getPropertyPath()方法获取字段的名称。

一个好的默认错误消息可以是:

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

在嵌套对象的情况下,哪个会给你“foo可能不为null”,或者“foo.bar可能不为null”。

答案 1 :(得分:2)

我不知道任何通用方法,但您可以定义自定义错误消息并在其中包含字段名称。

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

答案 2 :(得分:2)

我将每个字段验证消息放入属性文件中,如下所示:

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

并在bean中使用它:

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

我知道这不是一个完美的解决方案,但我也找不到更好的方法。

答案 3 :(得分:1)

如果您的消息位于.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;

OR

//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;

参考:message interpolation

答案 4 :(得分:1)

支持国际化的更好方法。

//在 ValidationMessages.properties 中

app.FieldName=MyField

app.validation.size.msg=size 必须介于 {min} 和 {max} 之间,但提供 ${validatedValue}

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

答案 5 :(得分:0)

使用oval这有很多注释和可能的方式来显示消息。

答案 6 :(得分:0)

对于那些正在寻找在验证器中访问类的方法的人。将hibernate注释放在类级别而不是变量级别上,可以访问类对象(假设您已经定义了自定义验证器)。

public class myCustomValidator implements ContraintValidator <MyAnnotation, MyAnnotatedClass> {

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

    public boolean isValid (MyAnnotatedClass myAnnotatedClass) {

        // access to elements of your myAnnotatedClass

    }
} 

答案 7 :(得分:0)

使用此方法(ex是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());


}

答案 8 :(得分:0)

如果在控制器中验证REST调用并使用控制器建议,则可以像下面这样组合来自MethodArgumentNotValidException的字段和默认消息:

@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception, HttpHeaders headers, HttpStatus status, WebRequest request) {
        String errorMessage = exception
                .getBindingResult()
                .getFieldErrors()
                .stream()
                .map(fieldError -> fieldError.getField() + " " + fieldError.getDefaultMessage())
                .collect(Collectors.joining(", "));


        return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
    }