Spring Boot中JSON参数与DTO类字段映射异常问题排查
问题描述
Spring Boot项目中使用Java DTO类映射输入参数时,字段名完全匹配的(如latitude)可正常取值,但像startDate对应输入中start_date这类遵循Java与JSON命名规范不一致的字段始终为null,尝试了@JsonProperty注解方案也无效。
JSON输入示例:
{ "latitude": 52.52, "longitude": 13.41, "start_date": "2023-05-08", "end_date": "2023-05-22" }
DTO类代码:
import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; @AllArgsConstructor @NoArgsConstructor @Getter @Setter @Builder public class InputParametersDTO { private float latitude; private float longitude; @JsonProperty("start_date") private String startDate; @JsonProperty("end_date") private String endDate; }
Controller代码:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import java.time.LocalDateTime; @RestController @RequestMapping("api/v1/demo") public class OpenMeteoController { @GetMapping @ResponseBody public ResponseEntity<?> getData(InputParametersDTO inputParametersDTO) throws Exception { float lat = inputParametersDTO.getLatitude(); // 正常取到52.52 String endDate = inputParametersDTO.getEndDate(); // 始终为null // 业务逻辑处理 return ResponseEntity.ok().build(); } }
解决方案
问题核心:你用的是@GetMapping,Spring处理Get请求参数时依赖DataBinder绑定URL/表单参数,而非Jackson解析JSON请求体,所以@JsonProperty注解不生效。以下是几种可行方案:
- 方案一:改用Post请求接收JSON体
把@GetMapping改为@PostMapping,并给DTO参数添加@RequestBody注解,这样Jackson会解析请求体中的JSON,@JsonProperty就能正常映射字段:
@PostMapping @ResponseBody public ResponseEntity<?> getData(@RequestBody InputParametersDTO inputParametersDTO) throws Exception { // 业务逻辑处理 return ResponseEntity.ok().build(); }
- 方案二:开启Spring MVC下划线转驼峰参数绑定
如果坚持用Get请求,在配置文件中添加以下配置,让Spring自动将下划线命名的参数(如start_date)映射到驼峰命名的DTO字段(如startDate):
application.properties:
spring.mvc.camel-case-to-hyphen=true spring.mvc.pathmatch.matching-strategy=ant_path_matcher spring.mvc.format.date=yyyy-MM-dd
application.yml:
spring: mvc: camel-case-to-hyphen: true pathmatch: matching-strategy: ant_path_matcher format: date: yyyy-MM-dd
添加配置后,DTO中的@JsonProperty注解可保留也可移除,不影响绑定效果。
- 方案三:手动指定请求参数映射
给每个字段添加@RequestParam注解明确指定参数名,适合字段较少的场景:
@GetMapping @ResponseBody public ResponseEntity<?> getData( @RequestParam float latitude, @RequestParam float longitude, @RequestParam("start_date") String startDate, @RequestParam("end_date") String endDate ) throws Exception { InputParametersDTO dto = InputParametersDTO.builder() .latitude(latitude) .longitude(longitude) .startDate(startDate) .endDate(endDate) .build(); // 业务逻辑处理 return ResponseEntity.ok().build(); }
内容的提问来源于stack exchange,提问作者Gianni Spear
相关产品推荐
相关产品推荐

