我尝试使用注释在我的REST bean上添加一些额外的验证逻辑。这只是一个示例,但重点是注释将用于多个REST资源对象/ DTO。
我希望得到这样的解决方案:
public class Entity {
@NotNull // JSR-303
private String name;
@Phone // Custom phonenumber that has to exist in a database
private String phoneNumber;
}
@Component
public class PhoneNumberValidator implements Validator { // Spring Validator
@Autowired
private PhoneRepository repository;
public boolean supports(Class<?> clazz) {
return true;
}
public void validate(Object target, Errors errors) {
Phone annotation = // find fields with annotations by iterating over target.getClass().getFields().getAnnotation
Object fieldValue = // how do i do this? I can easily get the annotation, but now I wish to do a call to repository checking if the field value exists.
}
}
答案 0 :(得分:0)
您是否尝试过像hibernate验证器这样的JSR 303 bean验证器实现 例如可在此处http://www.codejava.net/frameworks/spring/spring-mvc-form-validation-example-with-bean-validation-api
答案 1 :(得分:0)
Maven模块A:
public interface RestValidator<A extends Annotation, T> extends ConstraintValidator<A, T>
public interface PhoneValidator extends RestValidator<PhoneNumber, String>
@Target(FIELD)
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneValidator.class) // This usually doesnt work since its a interface
public @interface PhoneNumber {
// JSR-303 required fields (payload, message, group)
}
public class Person {
@PhoneNumber
private String phoneNumber;
}
Maven模块B:
@Bean
LocalValidatorFactoryBean configurationPropertiesValidator(ApplicationContext context, AutowireCapableBeanFactory factory) {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
factoryBean.setConstraintValidatorFactory(factory(context, factory));
return factoryBean;
}
private ConstraintValidatorFactory factory(final ApplicationContext context, final AutowireCapableBeanFactory factory) {
return new ConstraintValidatorFactory() {
@Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
if (RestValidator.class.isAssignableFrom(key)) {
return context.getBean(key);
} else {
return factory.createBean(key);
}
}
@Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
if (!(instance instanceof RestValidator<?, ?>)) {
factory.destroyBean(instance);
}
}
};
}
@Bean
WebMvcConfigurerAdapter webMvcConfigurerAdapter(final LocalValidatorFactoryBean validatorFactoryBean) {
return new WebMvcConfigurerAdapter() { // Adds the validator to MVC
@Override
public Validator getValidator() {
return validatorFactoryBean;
}
};
}
然后我有一个PhoneValidator的@Component实现,它有一个Scope = Prototype。
我讨厌这个解决方案,我认为Spring默认情况下应该查看Interface实现,但我确信有些比我聪明的人决定不这样做。