Spring validator: annotation and validator implementation

Is it possible to have annotations as a validator for the form and limitations?

For example, to have this field in a form object:

@NotEmpty private String date; 

but then check the date pattern in the validator.

I know there is an annotation for the template, but I just want to see if I can use both types of validation.

+4
source share
2 answers

Here is a link to a very good site that explains how you can combine the JSR-303 validator with the spring validator.

I will present the following my solution, which works. Hope this helps.

My abstract validator:

 import java.util.Map; import java.util.Set; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorFactory; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.validation.Errors; public abstract class AbstractValidator implements org.springframework.validation.Validator, ApplicationContextAware, ConstraintValidatorFactory { @Autowired private Validator validator; private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { Map<String, T> beansByNames = applicationContext.getBeansOfType(key); if (beansByNames.isEmpty()) { try { return key.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e); } catch (IllegalAccessException e) { throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e); } } if (beansByNames.size() > 1) { throw new RuntimeException("Only one bean of type '" + key.getName() + "' is allowed in the application context"); } return (T) beansByNames.values().iterator().next(); } public boolean supports(Class<?> c) { return true; } public void validate(Object objectForm, Errors errors) { Set<ConstraintViolation<Object>> constraintViolations = validator.validate(objectForm); for (ConstraintViolation<Object> constraintViolation : constraintViolations) { String propertyPath = constraintViolation.getPropertyPath().toString(); String message = constraintViolation.getMessage(); errors.rejectValue(propertyPath, "", message); } addExtraValidation(objectForm, errors); } protected abstract void addExtraValidation(Object objectForm, Errors errors); 

}

Valid Validator:

 import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import ro.scorpionsoftware.demo3.dao.AbstractValidator; @Component(value="doctorValidator") public class DoctorValidator extends AbstractValidator { @Override protected void addExtraValidation(Object objectForm, Errors errors) { //perform typical validation //can autowire to context } } 

Controller: (At the end, this is @Valid binding to the validator)

 @Controller public class DoctorEditController { @Autowired private DoctorValidator doctorValidator; @RequestMapping(value = "/doctorEdit", method = RequestMethod.POST) public String processSubmit( @ModelAttribute("doctorForm") @Valid DoctorForm df, BindingResult result, ModelMap model) { ... } @InitBinder protected void initBinder(WebDataBinder binder) { binder.setValidator(doctorValidator); } } 

In the context, declare the JSR-303 validator:

 <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> 

With this approach, you can get the context both in the actual validator and in any other custom annotation that you want to implement.

+3
source

You can annotate to use multiple validators, so it will be something like this.

 @NotEmpty @Pattern("") // not sure of syntax here @Target(ElementType.METHOD) @Retention( RetentionPolicy.RUNTIME) @Constraint(validatedBy = {}) @Documented public @interface DatePattern { String message() default ""; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } 
0
source

All Articles