fashuser
fashuser

Reputation: 1479

How to pass more parameters to spring validate method

I have extension of org.springframework.validation.Validator.

public class MyValidator implements Validator {

    @Override
        public void validate(Object target, Errors errors) {
        ...
    }
}

My goal is to pass more than one target to method.

I don't like idea with overload validate method because it smells as bad code: validate(Object target1, Object target1, Errors errors) or creating map with needed targets.

It will be good to know better approach regarding this case.

Upvotes: 2

Views: 12892

Answers (3)

Robert Ellis
Robert Ellis

Reputation: 734

i faced with a similar situation where i need to pass more arguments to the validate method so i came up with a idea of my own.in my case i wanted a String to be passed to this method

validate method implemented in the following classes CustomValidatorBean, LocalValidatorFactoryBean, OptionalValidatorFactoryBean, SpringValidatorAdapter

I extended the CustomValidatorBean and called the validate method in super class and it is working perfectly

import javax.validation.Validator;`
import org.apache.commons.lang3.StringUtils;`
import org.springframework.validation.Errors;`
importorg.springframework.validation.beanvalidation.CustomValidatorBean;`
public class MyValidator extends CustomValidatorBean {`
    public void myvalidate(Object target,Errors errors,String flag,Profile profile)
    {
        super.validate(target,errors);
        if(StringUtils.isEmpty(profile.name())){
            errors.rejectValue("name", "NotBlank.profilereg.name", new Object[] { "name" }, "Missing Required Fields");
        }       

    }           

}

Upvotes: 0

Cyril Deba
Cyril Deba

Reputation: 1210

I did not try the following code, but it demonstrates a basic idea how one field of the bean could be verified against the other. Hopefully, it will help you

Let's say you have the following form bean

public class MyForm {
    private String id;
    private List<String> oldIds;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public List<String> getOldIds() {
        return oldIds;
    }

    public void setOldIds(List<String> oldIds) {
        this.oldIds = oldIds;
    }

}

and the id property has to be validated against the oldIds object (if i did understand your requirements correctly). To achieve it your need to create a constraint and mark your bean. So, the first is the constraint interface

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.validation.Constraint;
import javax.validation.Payload;

@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
@Documented
public @interface MyConstraint {

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String[] value();
}

next, you need to implement the constraint validator class:

import java.util.List;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.apache.commons.beanutils.PropertyUtils;

public class MyConstraintValidator implements
    ConstraintValidator<MyConstraint, Object> {

    private String firstAttribute;
    private String secondAttribute;

    @Override
    public void initialize(final MyConstraint constraintAnnotation) {
        firstAttribute = constraintAnnotation.value()[0];
        secondAttribute = constraintAnnotation.value()[1];

    }

    @Override
    public boolean isValid(final Object object,
            final ConstraintValidatorContext constraintContext) {
        try {
            final String id = (String) PropertyUtils.getProperty(object,
                    firstAttribute);
            List<String> oldIds = (List<String>) PropertyUtils.getProperty(
                    object, secondAttribute);

            // do your validation

            return true;
        } catch (final Exception e) {
            throw new IllegalArgumentException(e);
        }

    }
}

finally, apply the created constraint to the form bean

@MyConstraint(value = { "id", "oldIds" })
public class MyForm {
    // the code
}

For now, your mark your bean with the @Valid annotation from the javax.validation package or feed it to the validator object

Upvotes: 6

kenor
kenor

Reputation: 1910

We use a target bean which holds all the data which need to be validated. Something like

private static final class ParamsBean {
  String id;
  List<String> oldIds;
}

Then we simply cast the object. It's the cleanest possible solution imo, as it does not use generic Map or List of unknown objects (though the casting still is not nice).

Upvotes: 4

Related Questions