Spring Validation: Требуется точная длина в необязательном поле
В Spring MVC я пытаюсь использовать аннотации для проверки правильности ввода формы. У меня есть некоторые поля, которые являются необязательными, но когда ввод предоставлен, он должен соответствовать определенным критериям. Например, у меня есть одно поле, которое можно оставить пустым, но когда оно заполнено, ответ должен быть ровно пять символов.
Я пробовал такие вещи, как
@Size(min=5, max=5)
private String value;
но это дает пользователю ошибку, если пользователь не заполняет поле.
Как я могу предоставить некоторые "правила" для необязательного поля?
2 ответа
- Первый вариант - установить значение на ноль.
Если вы посмотрите на SizeValidatorForCharSequence, используемый hibernate:
/**
* 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();
}
}
}
Размер недействителен, только если его длина не соответствует минимальным, максимальным ограничениям, и это нормально, если значение равно нулю.
Другой вариант - создать собственную аннотацию и валидатор:
@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(); } }
с валидатором
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;
}
....
}
Более простое решение - добавить метод в свой класс и добавить к нему аннотацию @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)
Вы можете использовать аннотацию @Pattern(regexp=""), чтобы разрешить настраиваемые шаблоны. После этого ошибка может быть показана с помощью Pattern. < Bean >.value=... в ваших файлах свойств i12n.
Пример:
В бобе "Персона":
Pattern(regexp="^[A-ZÑa-zñÁÉÍÓúáéíóú' -]{3,20}$")
private String names;
В messages.properties:
Pattern.person.names=Please insert a valid name