使用Spring Validator时抛出NotReadablePropertyException问题排查
分析与解决Spring Validator抛出NotReadablePropertyException的问题
让我来帮你拆解一下你遇到的问题——NotReadablePropertyException本质上是Spring无法正确访问目标对象的属性导致的,结合你的代码和场景,主要排查方向和修复方案如下:
1. 核心原因:JavaBean属性访问规范不匹配
Spring Validator依赖JavaBean的属性访问规则来读取对象属性,最常见的触发这个异常的情况是:
Jobs类中不存在recurrence属性,或者属性名拼写错误(比如写成recurrance)recurrence属性的getter方法不符合规范:必须是getRecurrence()(对于String类型),方法名大小写、拼写必须和属性名严格对应(属性是recurrence,getter就得是getRecurrence(),不能是getRecurr()或者其他变体)
检查你的Jobs类
确保你的Jobs类符合JavaBean规范,示例如下:
public class Jobs { // 属性名必须是recurrence(和你代码中调用的getRecurrence对应) private String recurrence; // 正确的getter方法 public String getRecurrence() { return recurrence; } // 可选:如果需要接收前端传入值,需要对应的setter public void setRecurrence(String recurrence) { this.recurrence = recurrence; } // 其他属性和方法... }
2. 代码逻辑的潜在问题(避免后续异常)
即使解决了属性访问问题,你的现有代码还存在两个隐患:
- 空指针风险:如果
recurrence为null,直接调用recurrence.equals(...)会抛出NullPointerException - 类型转换不安全:如果传入
validate方法的对象不是Jobs类型,强制转换会抛出ClassCastException
优化后的validate方法
@Override public void validate(Object obj, Errors errors) { // 先校验对象类型,避免强制转换错误 if (!(obj instanceof Jobs)) { errors.reject("invalid.object.type", "The input object is not a valid Jobs instance"); return; } Jobs job = (Jobs) obj; String recurrence = job.getRecurrence(); // 处理null场景 if (recurrence == null) { errors.rejectValue("recurrence", "recurrence.null", "Recurrence cannot be null"); return; } // 定义允许的5个特定值(用集合更简洁) Set<String> allowedValues = new HashSet<>(Arrays.asList( RecurrenceStatus.TEST, RecurrenceStatus.DAILY, RecurrenceStatus.WEEKLY, RecurrenceStatus.MONTHLY, RecurrenceStatus.YEARLY )); // 校验值是否合法 if (!allowedValues.contains(recurrence)) { errors.rejectValue( "recurrence", "recurrence.invalid", new Object[]{allowedValues}, "Recurrence must be one of: {0}" ); } }
3. 确保Validator正确集成和错误响应返回
最后,要确保你在Controller中正确使用Validator并处理错误结果,这样才能返回有意义的响应:
@PostMapping("/jobs") public ResponseEntity<?> createJob(@RequestBody Jobs job, BindingResult bindingResult) { // 手动调用Validator(如果没有用@Valid注解自动触发) validator.validate(job, bindingResult); if (bindingResult.hasErrors()) { // 收集错误信息并返回给前端 List<String> errorDetails = bindingResult.getAllErrors().stream() .map(error -> error.getDefaultMessage()) .collect(Collectors.toList()); return ResponseEntity.badRequest().body(Map.of("errors", errorDetails)); } // 正常业务逻辑 jobService.saveJob(job); return ResponseEntity.ok(job); }
总结一下,你当前的NotReadablePropertyException优先排查Jobs类的recurrence属性和getter方法是否符合JavaBean规范,这是最直接的解决方向。
内容的提问来源于stack exchange,提问作者Hermann Stahl
相关产品推荐
相关产品推荐

