【问题标题】:Include field name inside error message using Hibernate Validator使用 Hibernate Validator 在错误消息中包含字段名称
【发布时间】:2012-07-10 23:58:57
【问题描述】:

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

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

有没有更简洁的方法来实现这一点?

以下代码:

@Size(max = 5)
private String myField;

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

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

【问题讨论】:

    标签: java spring hibernate hibernate-validator


    【解决方案1】:

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

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

    【讨论】:

    • 那样没有国际化。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      public class myCustomValidator implements ContraintValidator <MyAnnotation, MyAnnotatedClass> {
      
          public void initialize (...){ ... };
      
          public boolean isValid (MyAnnotatedClass myAnnotatedClass) {
      
              // access to elements of your myAnnotatedClass
      
          }
      } 
      

      【讨论】:

        【解决方案4】:

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

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

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

        在嵌套对象的情况下,这会给你“foo may not be null”或“foo.bar may not be null”。

        【讨论】:

          【解决方案5】:

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

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

          在 bean 中,像这样使用它:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

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

              参考:message interpolation

              【讨论】:

              • 支持国际化的更好方法。 //在 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;
              【解决方案8】:

              如果在控制器中验证 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);
                  }
              

              【讨论】:

                【解决方案9】:

                支持国际化的更好方法。

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-04-10
                  • 2013-08-12
                  • 1970-01-01
                  相关资源
                  最近更新 更多