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

Spring Boot MockMvc测试Gson反序列化报Expected BEGIN_OBJECT异常

问题根因

报错核心原因是手动创建的原生Gson实例默认不支持JSR310规范的Java 8时间类型(如OffsetDateTime)反序列化。
生产环境、Postman调用能正常解析,是因为Spring Boot默认使用Jackson作为JSON解析框架,且自动加载了JavaTimeModule适配OffsetDateTime、LocalDateTime这类时间类型,可以直接将ISO格式的时间字符串转换为对应时间对象。但单元测试中你没有复用Spring已配置好的解析器,自己实例化的原生Gson遇到OffsetDateTime类型时,默认会期望对应值是嵌套对象结构(即解析到BEGIN_OBJECT标记),但实际拿到的是时间字符串,因此抛出该异常。

排查思路

按以下步骤可快速定位问题:

  • 打印response.getContentAsString()的完整内容,确认无多余转义字符、前后缀、BOM头,排除MockMvc响应内容编码异常、被额外包装的问题
  • 脱离MockMvc环境做最小复现:直接用new Gson()解析你给出的示例JSON和ExampleResponse类,会稳定复现相同报错,排除MockMvc请求流程的干扰
  • 对比生产与测试环境的解析逻辑差异:生产走Spring MVC内置的Jackson转换器,测试用了无额外配置的原生Gson,两边解析规则不一致
解决方案

任选其一即可,优先选择和生产逻辑一致的方案:

方案1:复用Spring内置Jackson解析器(推荐)

不要手动创建Gson实例,直接注入Spring Boot自动配置好的ObjectMapper,该实例默认已完成OffsetDateTime类型适配,无需额外配置:

// 单元测试中注入Spring上下文管理的ObjectMapper
@Autowired
private ObjectMapper objectMapper;

// 替换原有Gson解析逻辑
ExampleResponse exampleResponse = objectMapper.readValue(
    response.getContentAsString(), 
    ExampleResponse.class
);

方案2:给Gson注册时间类型适配器

如果确定要使用Gson做解析,需要在构建Gson实例时注册JSR310时间类型的适配模块:

// 构建带时间适配能力的Gson实例
Gson gson = new GsonBuilder()
        .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeAdapter())
        .create();

// 再执行解析即可正常转换
ExampleResponse exampleResponse = gson.fromJson(responseString, ExampleResponse.class);

使用该方案需要确认适配器的时间格式与接口返回的ISO 8601时间格式匹配,避免格式转换错误。

方案3:临时简化方案

如果仅为临时跑通单测,可暂时将ExampleResponse类中的birthDate、created字段类型改为String,拿到字符串值后再手动调用OffsetDateTime.parse()转换为时间对象。该方案与生产环境类定义不一致,不建议长期使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:18:35