28

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

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

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

以下代码:

@Size(max = 5)
private String myField;

产生默认错误:大小必须在 0 到 5 之间。

我希望它是:myField 大小必须在 0 到 5 之间。

4

9 回答 9

32

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

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

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

在嵌套对象的情况下,这将为您提供“foo 可能不为空”或“foo.bar 可能不为空”。

于 2013-08-30T14:28:57.080 回答
6

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

参考:消息插值

于 2018-11-07T15:03:57.217 回答
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;

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

于 2015-04-02T08:22:36.917 回答
2

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

@Size(max = 5, message = "myField size must be between 0 and 5")  
private String myField;
于 2012-07-11T12:34:36.563 回答
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}") 私有字符串 myField;

于 2021-06-01T04:28:16.613 回答
0

使用椭圆形这有很多注释和显示消息的可能方式。

于 2012-07-11T15:49:51.987 回答
0

对于所有正在寻找一种方法来访问验证器中的类的人。将休眠注释放在类级别而不是变量级别使您可以访问类对象(假设您已经定义了自定义验证器)。

public class myCustomValidator implements ContraintValidator <MyAnnotation, MyAnnotatedClass> {

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

    public boolean isValid (MyAnnotatedClass myAnnotatedClass) {

        // access to elements of your myAnnotatedClass

    }
} 
于 2012-09-20T15:34:12.293 回答
0

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


}
于 2016-08-11T08:44:49.990 回答
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);
    }
于 2020-12-01T11:10:35.990 回答