我可以使用注解和验证器验证嵌套对象,实现ConstraintValidator
。代码有一个条件验证语句,它应该验证嵌套对象。
它是这样做的:
@Override
public boolean isValid(ScheduleJobRequest value, ConstraintValidatorContext context) {
if (value.getJobType() != JobType.EXPORT) {
return true; // do not fail
}
final ExportRequestData exportData = value.getExportData();
if (exportData == null) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("NotEmpty")
.addPropertyNode("exportData").addConstraintViolation();
return false;
}
final Set<ConstraintViolation<ExportRequestData>> violations = validator.validate(exportData);
violations.forEach(violation -> context
.buildConstraintViolationWithTemplate(violation.getMessage())
.addConstraintViolation());
return violations.isEmpty();
}
因此,如果jobType
枚举是EXPORT
,它应该评估exportData
,这是另一个DTO。
我还有一个自定义错误处理程序;这在顶级验证中工作正常。这是通过覆盖handleMethodArgumentNotValid
来完成的:
我在那里读取了BindingResult
和它的FieldErrors
。但是,我注意到在这种情况下,我的嵌套对象没有出现在FieldErrors中。
(code片段):
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
BindingResult bindingResult = ex.getBindingResult();
final List<FieldError> fieldErrors = bindingResult.getFieldErrors();
// this does not show any errors for nested objects
理想情况下,我希望结果是无效属性的路径。FieldName可以是名称本身。
我错过了什么?
顺便说一句:每当我试图在验证器中设置propertyNode
时,就像这样:
violations.forEach(violation -> context
.buildConstraintViolationWithTemplate(violation.getMessage())
.addPropertyNode(violation.getPropertyPath().toString())
.addConstraintViolation());
我也得到了一个错误(java.lang.IllegalStateException: JSR-303 validated property .... does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access)
),我似乎也无法解决。(我尝试了几个SO答案)。
1条答案
按热度按时间643ylb081#
我发现了这个问题并解决了它。嵌套对象必须在父对象中有一个注解
@Valid
。我没有这样做,因为它对我来说似乎是重复的。我也不想每次都验证对象,我以为@Valid
会像this is a required field
一样。但它不是。添加注解可以工作,并为我提供了预期的路径属性作为奖励。
This answer helped give me some context.