apply custom validator in spring MVC controller in

2020-06-06 05:20发布

问题:

I have one registration page which uses custom valiadtor

public class CustomValidator implements Validator {

    private Validator validator;

    public CustomValidator(Validator validator) {
        this.validator = validator;
    }

    @SuppressWarnings("rawtypes")
    public boolean supports(Class clazz) {
        return Registration.class.equals(clazz);
    }

    public void validate(Object target, Errors errors) {

        validator.validate(target, errors);



        Registration myModel1 = (Registration) target;
        if (! myModel1.getConfirm_password().equals(myModel1.getPassword())) {
            errors.rejectValue("confirm_password", "confirm_password.confirm");
        }

    }
}

The problem is that i want to apply it on two forms so i am confused how to write this function with two classes. This function now has only Registration class . what if i also want Person class in it as well

public boolean supports(Class clazz) {
        return Registration.class.equals(clazz);
    }

Can i write multiple classes in that function

here is my controller

@InitBinder
    public void initBinder(final WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, null, new CustomDateEditor(new SimpleDateFormat("dd-MM-yyyy"), true));
        Validator validator = (Validator) binder.getValidator();
        binder.setValidator(new CustomValidator((org.springframework.validation.Validator) validator));
    }

回答1:

You could do this

public boolean supports(Class clazz) {
    return Registration.class.equals(clazz) || Another.class.equals(clazz);
}

Then your validate should do something like this

    public void validate(Object target, Errors errors) {
    validator.validate(target, errors);

    String password = null;
    String confirm = null;
    if (target instanceof Registration) {
        Registration registration = (Registration) target;
        password = registration.getPassword();
        confirm = registration.getConfirm_password();
    } else if (target instanceof Another) {
        Another another = (Another) target;
        password = another.getPassword();
        confirm = another.getConfirm_password();
    }
    if (! confirm.equals(password())) {
        errors.rejectValue("confirm_password", "confirm_password.confirm");
    }

}

I don't think you should use this probably it is better to use to separate classes is better for readability, and reduces complexity. To introduce hierarchy in your validators or Model objects (Vistor pattern) is not the best solution.



回答2:

It appears you only want to validate 2 classes because you want to duplicate the 'confirm password' validation where you have 2 password fields that should match. Instead, why not simply pass an interface to the validator?

public void validate(IPasswordContainer target, Errors errors) {
    if(!target.getConfirm_password().equals(target.getPassword())) {
        errors.rejectValue("confirm_password", "confirm_password.confirm");
    }
}


public boolean supports(Class clazz) {
    return IPasswordContainer.class.equals(clazz);
}