2

在前端有一个表单,其中包含一个填充了一些选项的选择框。该模型包含一个将由我的自定义约束验证的字段:

private @Options(values=OptionKeys.SALUTATIONS) String salutation;

效果很好。现在我想在前端有一个复选框或一个多值选择框,它使用以下代码段:

private @Options(values=OptionKeys.INTERESTS, optional=true) String[] interests;

这是约束接口和验证器代码:

@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = OptionsValidator.class)
@Documented
public @interface Options {
    String message() default "{com.example.web.form.constraints.Options.message}";
    Class<? extends Payload>[] payload() default {};
    Class<?>[] groups() default {};
    boolean optional() default false;
    OptionKeys values();
}

public class OptionsValidator implements ConstraintValidator<Options, String> {

    private List<String> values;
    private boolean optional;

    @Override
    public void initialize(Options params) {
        values = Arrays.asList(params.values().data);
        optional = params.optional();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        if (optional && StringUtils.isBlank(value)) {
            return true;
        }

        return value != null && values.contains(value);
    }

}

public static enum OptionKeys {
    SALUTATIONS(new String[] {
            "m",
            "f"
    }),

    INTERESTS(new String[] {
            "dummy"
    });

    public final String[] data;
    OptionKeys(String[] data) {
        this.data = data;
    }
}

是否可以以某种方式扩展验证器以检查String[]值还是我必须编写另一个(例如@MultiOptions)?

4

2 回答 2

1

可以使用Object并检查其类型instanceof

public class OptionsValidator implements ConstraintValidator<Options, Object> {
    private List<String> values;
    private boolean optional;

    @Override
    public void initialize(Options params) {
        values = Arrays.asList(params.values().data);
        optional = params.optional();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
        if (optional && value == null) {
            return true;
        }

        if (value instanceof String[]) {
            String[] valArray = (String[]) value;
            if (!optional && valArray.length == 0) {
                return false;
            }

            for (String val : valArray) {
                if (!values.contains(val)) {
                    return false;
                }
            }

            return true;
        } else if (value instanceof String) {
            String val = (String) value;
            if (optional && val.trim() == "") {
                return true;
            }

            return val != null && values.contains(val);
        }

        return false;
    }
}
于 2013-07-09T13:15:05.713 回答
1

您可以通过提供多个实现约束的 ConstraintValidators 来重用相同的注解来验证不同的类。在@Constraint注释定义中填写validatedBy所有适用的类:

@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = {OptionsValidator.class, OptionsStringArrayValidator.class})
@Documented
public @interface Options {
   ...
}

并创建相应的实现:

public class OptionsValidator implements ConstraintValidator<Options, String> {...}
public class OptionsStringArrayValidator implements ConstraintValidator<Options, String[]> {...}
于 2022-03-02T15:42:50.433 回答