我試圖使用JSR-303 Bean Validation API
和Spring's Validator
的組合來實現彈簧引導端點的一些自定義驗證邏輯。使用JSR-303和Spring的驗證器的組合實現自定義驗證邏輯
基於驗證類圖上看來是可能延長的CustomValidatorBean
,SpringValidatorAdapter
或LocalValidatorFactoryBean
一個添加一些自定義驗證邏輯成重寫方法validate(Object target, Errors errors)
。
但是,如果我創建了一個驗證程序來擴展這三個類中的任何一個,並使用@InitBinder
註冊它,那麼將不會調用其validate(Object target, Errors errors)
方法,也不會執行驗證。如果我刪除@InitBinder
,那麼默認的彈簧驗證器執行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
所有的一起,但必須有一種方法來使自定義驗證工作。
春天validation documentation不上結合兩個超清晰:
應用程序也可以爲每個DataBinder的實例註冊附加彈簧驗證實例,如第9.8.3節「配置一個DataBinder的」。這對於插入驗證邏輯而不使用註釋可能很有用。
再後來上倒是上配置多個驗證實例
甲DataBinder的也可以與經由dataBinder.addValidators和dataBinder.replaceValidators多個驗證程序實例進行配置。將全局配置的Bean驗證與在DataBinder實例上本地配置的Spring驗證器相結合時,這非常有用。見???。
我使用的是spring boot 1.4.0。
我不完全確定它很清楚你的實際問題是什麼。此外,如果你分享了一個完整的例子(例如整個代碼)。那麼我們很容易幫助你。 –
您是否閱讀過文檔?在'Validator'中只實現你的自定義邏輯,並使用'addValidators'而不是'setValidator'。這將調用JSR-303(默認配置的驗證器)和您自定義的一個。但是,您可能更好地使用JSR-303驗證程序/約束,而不是使用2種不同的機制。 –
Thanks @ M.Deinum - 使用'addValidators'而不是'setValidator'完成了這個訣竅。我也同意使用JSR-303,專門用於交叉字段驗證的@AssertTrue方法,可能是一個更乾淨的解決方案。代碼示例可在https://github.com/pavelfomin/spring-boot-rest-example/tree/feature/custom-validator中找到。在 的示例中,中間名驗證通過自定義彈簧 驗證程序執行,而姓名驗證由缺省jsr 303 驗證程序處理。 – pavel