弹簧验证:要求可选字段的精确长度

时间:2015-02-10 02:03:39

标签: java spring validation spring-mvc spring-form

在Spring MVC中,我尝试使用注释来执行表单输入的验证。我有一些可选的字段,但是当提供输入时,它必须满足某些条件。例如,我有一个字段可以留空,但填写后,答案必须正好是五个字符。

我尝试过像

这样的事情
@Size(min=5, max=5)
private String value;

但如果用户没有填写该字段,则会给用户带来错误。

我如何提供一些规则"对于可选字段?

3 个答案:

答案 0 :(得分:4)

  1. 第一个选项是将 value 设置为null。
  2. 如果你看一下hibernate使用的SizeValidatorForCharSequence:

    /**
     * Check that the length of a character sequence is between min and max.
     *
     * @author Emmanuel Bernard
     * @author Gavin King
     * @author Hardy Ferentschik
     */
    public class SizeValidatorForCharSequence implements ConstraintValidator<Size, CharSequence> {
    
        private static final Log log = LoggerFactory.make();
    
        private int min;
        private int max;
    
        public void initialize(Size parameters) {
            min = parameters.min();
            max = parameters.max();
            validateParameters();
        }
    
        /**
         * Checks the length of the specified character sequence (e.g. string).
         *
         * @param charSequence The character sequence to validate.
         * @param constraintValidatorContext context in which the constraint is evaluated.
         *
         * @return Returns <code>true</code> if the string is <code>null</code> or the length of <code>charSequence</code> between the specified
         *         <code>min</code> and <code>max</code> values (inclusive), <code>false</code> otherwise.
         */
        public boolean isValid(CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) {
            if ( charSequence == null ) {
                return true;
            }
            int length = charSequence.length();
            return length >= min && length <= max;
        }
    
        private void validateParameters() {
            if ( min < 0 ) {
                throw log.getMinCannotBeNegativeException();
            }
            if ( max < 0 ) {
                throw log.getMaxCannotBeNegativeException();
            }
            if ( max < min ) {
                throw log.getLengthCannotBeNegativeException();
            }
        }
    }
    

    只有当长度与最小,最大约束不匹配时,大小才有效,如果值为空,则大小无效。

    1. 另一种选择是创建自己的注释和验证器:

      @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
      @Retention(RUNTIME)
      @Documented
      @Constraint(validatedBy = { StringEmptyOrSizeValidator.class })
      public @interface StringEmptyOrSize {
      
          String message() default "{javax.validation.constraints.Size.message}";
      
          Class<?>[] groups() default { };
      
          Class<? extends Payload>[] payload() default { };
      
          /**
           * @return size the element must be higher or equal to
           */
          int min() default 0;
      
          /**
           * @return size the element must be lower or equal to
           */
          int max() default Integer.MAX_VALUE;
      
          /**
           * Defines several {@link Size} annotations on the same element.
           *
           * @see Size
           */
          @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
          @Retention(RUNTIME)
          @Documented
          @interface List {
      
              Size[] value();
          }
      }
      
    2. 使用验证器

      public class StringEmptyOrSizeValidator implements ConstraintValidator<Size, CharSequence> {
      
          ....
          public boolean isValid(CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) {
              if ( charSequence == null || charSequence.isEmpty()) {
                  return true;
              }
              int length = charSequence.length();
              return length >= min && length <= max;
          }
      
          ....
      }
      

答案 1 :(得分:0)

您可以使用 @Pattern(regexp =“”)注释来允许自定义模式。之后,错误可以在您的i12n属性文件中以 Pattern。&lt; bean&gt; .value = ... 显示。

示例:

在豆“人”中:

Pattern(regexp="^[A-ZÑa-zñÁÉÍÓúáéíóú' -]{3,20}$")
private String names;

在messages.properties中:

Pattern.person.names=Please insert a valid name

答案 2 :(得分:0)

一个更简单的解决方案是在您的类中添加一个方法,并向其添加@AssertTrue批注,如下所示:

@AssertTrue
public boolean isValidValue() {
        if(this.value == null || this.value.isEmpty()) {
            return true;
        }
        else {
            return this.value.length() == 5 ? false: true;
        }
    }

与此无关,您不需要:@Size(min=5, max=5)