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

JSON映射DTO时报Cannot deserialize instance of out of START_ARRAY token如何解决

报错原因

这个错误是Jackson反序列化时类型不匹配导致的:你配置的反序列化目标是PersonDto对象(对应JSON结构{...}),但Jackson实际解析时拿到的是数组开头的START_ARRAY令牌(对应JSON结构[...]),触发原因是PersonDto上的@JsonRootName注解配置和反序列化逻辑不匹配。

你当前的JSON结构外层是对象,内部data字段才是人员数组,而PersonDto本身已经定义了List<PersonDetail> data字段和JSON结构完全匹配,额外加的@JsonRootName(value = "data")注解是多余的:如果你的Jackson全局配置开了DeserializationFeature.UNWRAP_ROOT_VALUE,反序列化时会直接剥离外层JSON对象,取data字段对应的数组内容直接映射到PersonDto,自然会抛出数组转对象的类型不匹配错误。

修复方案

方案1(推荐,改动最小)

直接删除PersonDto类上的@JsonRootName(value = "data")注解即可,无需修改其他代码。
修改后的PersonDto示例:

@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class PersonDto {

    List<PersonDetail> data = Lists.newArrayList();

    @Builder(toBuilder = true)
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public static class PersonDetail {
        @JsonProperty("firstname")
        private String firstname;
        @JsonProperty("lastname")
        private String lastName;
        @JsonProperty("email")
        private String email;
    }
}

调用接口时仍然传入PersonDto.class作为响应类型参数,即可正常完成反序列化。

方案2(保留根节点解析配置)

如果你确实需要开启UNWRAP_ROOT_VALUE全局配置,可以删除PersonDto包装类,直接将响应类型指定为List<PersonDto.PersonDetail>,但需要修改你的post方法支持泛型类型解析:

  1. 新增支持ParameterizedTypeReference的重载方法:
public <T, K> Mono<T> post(ParameterizedTypeReference<T> respType, K reqDto, Function<UriBuilder, URI> pathFunction, String token) {
    return webClient
            .post()
            .uri(pathFunction)
            .body(BodyInserters.fromValue(reqDto))
            .header(HttpHeaders.AUTHORIZATION, BEARER + token)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .accept(MediaType.APPLICATION_JSON)
            .acceptCharset(StandardCharsets.UTF_8)
            .exchange()
            .flatMap(clientResponse -> {
                if (clientResponse.statusCode().is2xxSuccessful()) return clientResponse.bodyToMono(respType);
                return clientResponse.createException().flatMap(Mono::error);
            });
}
  1. 调用时传入泛型类型即可:
post(new ParameterizedTypeReference<List<PersonDto.PersonDetail>>() {}, reqDto, pathFunc, token)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 05:45:03