SpringBoot+Thymeleaf出现NotReadablePropertyException校验报错求助
我之前也踩过这个坑!你遇到的org.springframework.beans.NotReadablePropertyException异常,本质是Spring找不到你在errors.rejectValue()里指定的startStatusDate属性,大概率是下面几个原因之一:
属性名拼写不一致:仔细核对你的实体类(或表单DTO)里的字段名,是不是和Validator里写的
startStatusDate完全一致?比如有没有大小写错误(比如实体类里是startstatusDate,或者你写成了startStatusdate),哪怕一个字母大小写错了,Spring都找不到对应的属性。缺少对应的Getter方法:Spring的校验框架在处理错误信息时,需要通过getter方法访问属性。如果你的实体类只有
startStatusDate字段,但没有getStartStatusDate()方法,就会触发这个异常。一定要确保每个用于页面绑定和校验的属性都有正确的getter(表单对象通常还需要setter)。校验对象类型不匹配:检查
validate(Object o, Errors errors)方法里的o是不是你期望的实体类/表单对象。比如如果传入的是其他类型的对象,你却用startStatusDate作为属性名,自然找不到。建议在方法开头先做类型转换,避免类型错误:DriverHistoryForm form = (DriverHistoryForm) o;然后基于转换后的对象做校验逻辑,这样更稳妥。
Thymeleaf页面绑定字段不一致:虽然页面能正常运行,但也要确认页面输入框的绑定字段和Validator里的属性名一致。比如Thymeleaf里是不是写的
th:field="*{startStatusDate}",确保和Validator中rejectValue的第一个参数完全匹配。
给你一个正确的Validator示例参考:
public class DriverHistoryValidator implements Validator { @Override public boolean supports(Class<?> clazz) { // 指定这个Validator支持的对象类型 return DriverHistoryForm.class.isAssignableFrom(clazz); } @Override public void validate(Object o, Errors errors) { DriverHistoryForm form = (DriverHistoryForm) o; LocalDate start = form.getStartStatusDate(); LocalDate end = form.getEndStatusDate(); // 时间区间校验逻辑 if (start != null && end != null && start.isAfter(end)) { errors.rejectValue("startStatusDate", "co.driverHistoryStatusPeriod.notpermitted"); // 也可以给endStatusDate添加错误提示,比如: // errors.rejectValue("endStatusDate", "co.driverHistoryStatusPeriod.notpermitted"); } } }
对应的实体类/表单DTO要确保有正确的getter/setter:
public class DriverHistoryForm { private LocalDate startStatusDate; private LocalDate endStatusDate; // 必须存在的getter public LocalDate getStartStatusDate() { return startStatusDate; } public void setStartStatusDate(LocalDate startStatusDate) { this.startStatusDate = startStatusDate; } // endStatusDate的getter和setter同理 public LocalDate getEndStatusDate() { return endStatusDate; } public void setEndStatusDate(LocalDate endStatusDate) { this.endStatusDate = endStatusDate; } }
按照上面的步骤排查,应该就能解决这个异常了。
内容的提问来源于stack exchange,提问作者Scirocco

