使用@PostMapping接收请求时isRaining字段始终返回false的问题
问题描述
我有Measurement类和对应的MeasurementDTO,相关代码及问题如下:
MeasurementDTO 代码
@Data public class MeasurementDTO { @Column(name = "measurement_temp") private double temp; @Column(name = "measurement_raining") private boolean isRaining; @NotEmpty @NotNull private String sensorName; }
控制器代码
@PostMapping("/add") private ResponseEntity<HttpStatus> add(@RequestBody @Valid MeasurementDTO measurementDTO, BindingResult bindingResult){ System.out.println(measurementDTO.isRaining()); // 始终返回false if(bindingResult.hasErrors()){ StringBuilder errorMsg = new StringBuilder(); List<FieldError> errors = bindingResult.getFieldErrors(); for (FieldError error : errors) errorMsg.append(error.getField()) .append(" - ") .append(error.getDefaultMessage()) .append("; "); throw new MeasurementNotCreatedException(errorMsg.toString()); } if(sensorService.getAll().stream().anyMatch(s -> s.getName().equals(measurementDTO.getSensorName()))) Measurement measurement = convertToMeasurement(measurementDTO); measurement.setSensor(sensorService.getByName(measurementDTO.getSensorName())); measurementService.save(measurement); return new ResponseEntity<>(HttpStatus.OK); } else throw new SensorNotFoundException(); }
使用Postman发送POST请求,请求体如下:
{ "isRaining" : true, "temp" : 24.0, "sensorName" : "new sensor" }
但measurementDTO.isRaining()始终返回false,需排查原因并给出解决方法。
原因分析
核心问题是Jackson的属性映射规则与Java布尔字段命名的冲突:
- Lombok的
@Data注解会给isRaining字段生成isRaining()getter方法,符合JavaBean布尔类型命名规范。 - Jackson默认会根据Java类的属性名匹配JSON键,对于布尔类型字段,它会自动去掉
is前缀,将isRaining识别为属性raining,因此无法匹配请求体中的isRaining键,最终字段保留默认值false。
另外,控制器代码存在语法错误:if语句未加花括号,导致仅第一行代码属于if块,后续代码会无条件执行,不过这和当前isRaining问题无关,但建议修复。
解决方法
提供两种可行修复方案:
方案一:修改JSON请求体的键名
将请求体中的isRaining改为raining,适配Jackson的默认映射规则:
{ "raining" : true, "temp" : 24.0, "sensorName" : "new sensor" }
方案二:添加Jackson注解指定JSON键名
保留原请求体结构,给isRaining字段添加@JsonProperty注解,明确指定对应的JSON键名:
@Data public class MeasurementDTO { @Column(name = "measurement_temp") private double temp; @Column(name = "measurement_raining") @JsonProperty("isRaining") // 指定JSON中对应的键名 private boolean isRaining; @NotEmpty @NotNull private String sensorName; }
额外修复:修正控制器语法错误
原控制器的if语句缺少花括号会导致逻辑错误,修改后代码如下:
if(sensorService.getAll().stream().anyMatch(s -> s.getName().equals(measurementDTO.getSensorName()))) { Measurement measurement = convertToMeasurement(measurementDTO); measurement.setSensor(sensorService.getByName(measurementDTO.getSensorName())); measurementService.save(measurement); return new ResponseEntity<>(HttpStatus.OK); } else throw new SensorNotFoundException();
内容的提问来源于stack exchange,提问作者Юрій Огоновський
相关产品推荐
相关产品推荐

