Spring 3.1 AutoWiring在自定义约束验证器中不起作用
-
12-12-2019 - |
题
我在自定义约束验证程序内部有bean autowiring的问题。不使用Spring的LocalValidatorFactoryBean给出约束验证器实例。 JSR-303提供程序是Hibernate验证器4.2.0.final。
弹簧配置摘录:
<!-- 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 {};
}
.
someservice:
@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
}
...
}
.
omeypeservice是另一个@service annotated bean,不依赖于someservice ...
问题是我获得了一个npe,因为自动控制不起作用;其他人正在管理自定义验证器实例而不是Spring ...
提前感谢任何类型的建议。
解决方案
发现了问题。方法ValidationPostPostProcessor和MVC中必须使用相同的“验证器”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" />
...
其他提示
tito,请检查您是否可以使用如下面的java配置:
@Configuration
public class SampleConfig {
...
@Bean
public Validator validator() {
return new LocalValidatorFactoryBean().getValidator();
}
@Bean
public MethodValidationPostProcessor mvpp() {
MethodValidationPostProcessor mvpp = new MethodValidationPostProcessor();
mvpp.setValidator(validator());
return mvpp;
}
...
}
.
要在不同的配置bean中重用验证器bean,您可以使用@import注释。