java使用JSR303和spring的验证器的组合为spring引导端点实现自定义验证逻辑
我正在尝试使用JSR-303 Bean Validation API
和Spring's Validator
的组合为spring引导端点实现一些自定义验证逻辑
根据验证器类图,似乎可以扩展CustomValidatorBean
、SpringValidatorAdapter
或LocalValidatorFactoryBean
中的一个,将一些自定义验证逻辑添加到重写的方法validate(Object target, Errors errors)
然而,如果我创建一个扩展这三个类中任何一个的验证器,并使用@InitBinder
注册它,它的validate(Object target, Errors errors)
方法永远不会被调用,也不会执行任何验证。如果我删除@InitBinder
,那么默认的spring验证器将执行JSR-303 Bean Validation
休息控制器:
@RestController
public class PersonEndpoint {
@InitBinder("person")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new PersonValidator());
}
@RequestMapping(path = "/person", method = RequestMethod.PUT)
public ResponseEntity<Person> add(@Valid @RequestBody Person person) {
person = personService.save(person);
return ResponseEntity.ok().body(person);
}
}
自定义验证程序:
public class PersonValidator extends CustomValidatorBean {
@Override
public boolean supports(Class<?> clazz) {
return Person.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
super.validate(target, errors);
System.out.println("PersonValidator.validate() target="+ target +" errors="+ errors);
}
}
如果我的验证器实现了org.springframework.validation.Validator
,那么它的validate(Object target, Errors errors)
方法会被调用,但JSR-303 Bean Validation
不会在它之前执行。我可以实现自定义JSR-303验证,类似于SpringValidatorAdapter
实现其JSR-303 Bean Validation
的方式,但必须有一种方法来扩展它:
@Override
public void validate(Object target, Errors errors) {
if (this.targetValidator != null) {
processConstraintViolations(this.targetValidator.validate(target), errors);
}
}
我已经研究过如何使用自定义JSR-303约束来避免同时使用org.springframework.validation.Validator
,但必须有一种方法使自定义验证器工作
Spring validation documentation在结合这两个方面并不十分明确:
An application can also register additional Spring Validator instances per DataBinder instance, as described in Section 9.8.3, “Configuring a DataBinder”. This may be useful for plugging in validation logic without the use of annotations.
然后在后面,它涉及到配置多个验证器实例
A DataBinder can also be configured with multiple Validator instances via dataBinder.addValidators and dataBinder.replaceValidators. This is useful when combining globally configured Bean Validation with a Spring Validator configured locally on a DataBinder instance. See ???.
我使用的是spring boot 1.4.0
# 1 楼答案
这个问题可以通过扩展LocalValidatoryFactoryBean来解决,您可以重写这个类中的
validate
方法,给出您想要的任何行为在我的例子中,我需要在同一个控制器的不同方法中使用JSR-303和同一模型的自定义验证器,通常建议使用@InitBinder,但这对于我的案例来说还不够,因为InitBinder在模型和验证器之间进行绑定(如果您使用@RequestBody InitBinder,那么它只针对一个模型和每个控制器一个验证器)
控制器
自定义验证器
类进行验证
CustomLocalValidatoryBean
配置应用程序
输入到
/test
端点:来自
/test
端点的输出:输入到
/test2
端点:输出到
/test2
端点:我希望这能有所帮助