问题描述
我在自定义约束验证器中遇到 bean 自动装配问题.没有使用 Spring 的 LocalValidatorFactoryBean 给出约束验证器实例.JSR-303 提供程序是 hibernate-validator 4.2.0.Final.
Spring 配置摘录:
<!-- JSR 303 validation --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
自定义约束验证器:
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.springframework.beans.factory.annotation.Autowired; import com.model.Subject; import com.services.SomeTypeService; public class ReadOnlyValidator implements ConstraintValidator<ReadOnly, String> { @Autowired private SomeTypeService someTypeService; @Override public void initialize(ReadOnly constraintAnnotation) { } @Override public boolean isValid(String type, ConstraintValidatorContext context) { try { if (null != type) { return !someTypeService.isReadonly(type); } } catch (Exception e) { e.printStackTrace(); } return false; } }
注释:
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Target( { METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER } ) @Retention(RUNTIME) @Constraint(validatedBy = ReadOnlyValidator.class) @Documented public @interface ReadOnly { String message() default "{constraints.subjecttype.readonly}"; public abstract Class<?>[] groups() default {}; public abstract Class<? extends Payload>[] payload() default {}; }
一些服务:
@Validated public interface SomeService { ... public void updateType(@ReadOnly String type) throws SomeException; ... }
SomeServiceImpl :
@Service public class SomeServiceImpl implements SomeService { ... public void updateType(String type) throws SomeException { // do something } ... }
SomeTypeService 是另一个不依赖于 SomeService 的 @Service 注释 bean ...
问题是我得到一个 NPE,因为自动装配不起作用;其他人正在管理自定义验证器实例,而不是 Spring ...
提前感谢任何类型的建议.
推荐答案
找到问题了.MethodValidationPostProcessor 和 mvc:annotation-driven 声明必须使用相同的"验证器"bean 引用:
service-context.xml
<!-- JSR 303 validation --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"> <property name="validator" ref="validator"/> </bean> ...
dispatcher-servlet.xml
... <mvc:annotation-driven validator="validator" /> ...