You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

REST接口Controller如何接收含Map属性DTO并解决反序列化报错

问题根因
  • 报文结构与DTO类型不匹配:quotes字段定义为Map<LocalDate, Double>类型时,Jackson默认要求对应JSON位置传入键值对结构的JSON对象,但当前请求中quotes传的是JSON数组,数组内对象的属性名(如quoteDate)会被Jackson尝试解析为Map的key,自然无法转换为LocalDate类型,直接触发解析异常。
  • Jackson默认能力缺失:即使报文结构调整正确,Jackson默认也不支持直接将字符串类型的Map key反序列化为java.time.LocalDate类型,需要额外指定反序列化规则。
解决方案

二选一即可,根据业务场景选择:

方案1:保留Map类型,调整报文+配置反序列化规则

如果业务上确实需要quotes为日期为键、价格为值的Map结构,按以下步骤修改:

  1. 调整请求JSON,将quotes从数组改为键值对对象:
{
    "stockId": "test3",
    "quotes": {
        "2003-05-14": 35.9,
        "2016-03-28": 55.0
    }
}
  1. 为Map字段指定key反序列化器,Spring Boot 2.x+默认自带jackson-datatype-jsr310依赖,无需额外引入包:
import com.fasterxml.jackson.datatype.jsr310.deser.key.LocalDateKeyDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.time.LocalDate;
import java.util.Map;

public class StockDTO {
    private String id;
    private String stockId;
    @JsonDeserialize(keyUsing = LocalDateKeyDeserializer.class)
    private Map<LocalDate, Double> quotes;

    // 自行补全getter、setter、toString方法
}
  1. (可选)全局配置:如果项目里有多个LocalDate类型为key的Map,可以直接全局注册JavaTime模块,省掉每个字段加注解的步骤:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
    }
}

方案2:调整DTO结构匹配现有报文

如果不需要强用Map类型,直接修改DTO适配当前发送的数组结构,配置更简单,代码可读性也更高:

  1. 定义报价子对象:
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;

public class QuoteDTO {
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate quoteDate;
    private Double quoteValue;

    // 自行补全getter、setter
}
  1. 修改StockDTO的quotes字段类型:
import java.util.List;

public class StockDTO {
    private String id;
    private String stockId;
    private List<QuoteDTO> quotes;

    // 自行补全getter、setter、toString方法
}

这种方式不需要额外全局配置,直接用原有Postman报文即可正常解析。

内容的提问来源于stack exchange,提问作者Bruno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:18:19