简体   繁体   中英

Custom Constraint(Validator) for different Types

On the frontend side there's a form containing a selectbox filled with some options. The model contains a field which will be validated by my custom constraint:

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

Which works great. Now I would like to have checkboxes or a multi value selectbox on the frontend side which uses the following snippet:

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

Here's the constraint interface and the validator code:

@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;
    }
}

Is it possible to extend the validator somehow to also check String[] values or do I have to write another one (eg @MultiOptions )?

One could use Object and check its type with 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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM