在Spring MVC验证中,每个字段一次只能显示一条错误消息



示例,

我有

@NotEmpty //tells you 'may not be empty' if the field is empty
@Length(min = 2, max = 35) //tells you 'length must be between 2 and 35' if the field is less than 2 or greater than 35
private String firstName;

然后我输入一个空值。

上面写着"可能不是空的"长度必须在2到35'之间

有没有可能告诉spring在每个字段一次验证一个?

是的,这是可能的。只需创建自己的注释如下:

@Documented
@Constraint(validatedBy = {})
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@ReportAsSingleViolation
@NotEmpty
@Length(min = 2, max = 35)
public @interface MyAnnotation {
    public abstract String message() default "{mypropertykey}";
    public abstract Class<?>[] groups() default {};
    public abstract Class<?>[] payload() default {};
}

重要的部分是@ReportAsSingleViolation注释

为字段使用自定义约束。例如,将使用注释@StringField

@Target(ElementType.FIELD)
@Constraint(validatedBy = StringFieldValidator.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface StringField {
    String message() default "Wrong data of string field";
    String messageNotEmpty() default "Field can't be empty";
    String messageLength() default "Wrong length of field";
    boolean notEmpty() default false;
    int min() default 0;
    int max() default Integer.MAX_VALUE;
    Class<?>[] groups() default {};
    Class<?>[] payload() default {};
} 

然后在StringFieldValidator类中做一些逻辑。该类由接口ConstraintValidator <A extends Annotation, T>实现。

public class StringFieldValidator implements ConstraintValidator<StringField, String> {
    private Boolean notEmpty;
    private Integer min;
    private Integer max;
    private String messageNotEmpty;
    private String messageLength;
    @Override
    public void initialize(StringField field) {
        notEmpty = field.notEmpty();
        min = field.min();
        max = field.max();
        messageNotBlank = field.messageNotEmpty();
        messageLength = field.messageLength();
    }
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        context.disableDefaultConstraintViolation();
        if (notEmpty && value.isEmpty()) {
            context.buildConstraintViolationWithTemplate(messageNotEmpty).addConstraintViolation();
            return false;
        }
        if ((min > 0 || max < Integer.MAX_VALUE) && (value.length() < min || value.length() > max)) {
            context.buildConstraintViolationWithTemplate(messageLength).addConstraintViolation();
            return false;
        }
        return true;
    }
}

然后你可以使用这样的注释:

@StringField(notEmpty = true, min = 6, max = 64,
            messageNotEmpty = "Field can't be empty",
            messageLength = "Field should be 6 to 64 characters size")

毕竟,您将只显示一条按正确顺序显示的错误消息。

更好的解决方案是在错误消息中添加一些标记,使其格式良好,例如<br />,并使用CSS类来格式化整个消息。正如Bozhao的评论中所指出的,用户应该意识到所有不正确的地方。

最新更新