<Object> 使用 Spring 验证器验证列表



问题:如何在验证器中为List目标的Errors设置正确的嵌套路径以调用其他验证器?

代码参考:嵌套对象的嵌套弹簧验证器

public class AllergyDtoListValidator implements Validator {
private AllergyDtoValidator allergyDtoValidator;
@Override
public boolean supports(Class<?> clazz) {
return new TypeToken<List<AllergyDto>>() {
}.getType().equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
allergyDtoValidator = new AllergyDtoValidator();
List<AllergyDto> request = (List<AllergyDto>) target;
for (int i = 0; i < request.size(); i++) {
// below line causes the exception
errors.pushNestedPath(String.valueOf(i));
ValidationUtils.invokeValidator(this.allergyDtoValidator, request.get(i), errors);
errors.popNestedPath();
}
}
}
public class AllergyDtoValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return AllergyDto.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
AllergyDto request = (AllergyDto) target;
log.info("Enter allergy validator {}", request.toString());
try {
// field allergyTypeCode
if (request.getAllergyTypeCode() == null || request.getAllergyTypeCode().isEmpty()) {
errors.rejectValue("allergyTypeCode", "Cannot be null nor whitespace");
} else if (request.getAllergyTypeCode().length() > 8) {
errors.rejectValue("allergyTypeCode", "Exceed max length");
}
// field allergyCode
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "allergyCode", "Cannot be null nor "
+ "whitespace");
if (request.getAllergyCode() != null && request.getAllergyCode().length() > 8) {
errors.rejectValue("allergyCode", "Exceed max length");
}
// field allergyName
if (request.getAllergyName() != null && request.getAllergyName().length() > 66) {
errors.rejectValue("allergyName", "Exceed max length");
}
// field remarks
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "remarks", "Cannot be null nor whitespace");
if (request.getRemarks() != null && request.getRemarks().length() > 255) {
errors.rejectValue("remarks", "Exceed max length");
}
} catch (Exception e) {
log.info("Exception {}", e);
}
log.info("allergy errors {}", errors.toString());
}
}
public class AllergyDto implements Serializable {
private static final long serialVersionUID = 2319040437020676767L;
@JsonProperty("allergy_type_code")
private String allergyTypeCode;
@JsonProperty("allergy_code")
private String allergyCode;
@JsonProperty("allergy_name")
private String allergyName;
@JsonProperty("remarks")
private String remarks;
// getters and setters
}

当我运行时

// req is List<AllergyDto>
allergyDtoListValidator.validate(req, bindingResult);

我得到了异常

org.springframework.beans.NotReadablePropertyException:无效bean类[java.util.ArrayList]的属性"0":bean属性"0(为不可读或具有无效的getter方法:的返回类型getter与setter的参数类型匹配吗?在org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:627(在org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:843(在org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:820(在org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:615(在org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:104(在org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:228(在org.springframework.validation.ValidationUtils.rejectIfEmptyOrWhitespace(ValidationUtils.java:252(在org.springframework.validation.ValidationUtils.rejectIfEmptyOrWhitespace(ValidationUtils.java:191(在sg.gov.hpb.yhms.medical_service.validators.AllergyDtoValidator.validate(AllergyDtoValidator.java:32(在org.springframework.validation.ValidationUtils.invokeValidator(ValidationUtils.java:89(在org.springframework.validation.ValidationUtils.invokeValidator(ValidationUtils.java:56(在sg.gov.hpb.yhms.medical_service.validators.AllergyDtoListValidator.validate(AllergyDtoListValidator.java:32(

org.springframework.validation.Validator无法将List<Object>验证为target。您必须使用getter将List包装在一个Object中,以便验证器找到访问子对象的路径。

public class AllergyDtoListValidator implements Validator {
private AllergyDtoValidator allergyDtoValidator;
@Override
public boolean supports(Class<?> clazz) {
return AllergyDtoList.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
allergyDtoValidator = new AllergyDtoValidator();
AllergyDtoList request = (AllergyDtoList) target;
for (int i = 0; i < request.size(); i++) {
// sub path name must be same as property name to enable Validator to use 
// getter in the object AllergyDtoList
errors.pushNestedPath("allergies["+i+"]");
ValidationUtils.invokeValidator(this.allergyDtoValidator, request.get(i), errors);
errors.popNestedPath();
}
}
}
// new wrapping object to be validated 
class AllergyDtoList {
List<AllergyDto> allergies;
}

最新更新