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

使用RestTemplate exchange反序列化JSON遇类型转换异常求助

问题原因分析

异常核心是JSON结构与你期望的Java类型不匹配:你想反序列化为HashMap<String, Person>,但返回的JSON里,每个键(比如scully)对应的值是一个Person对象数组([ {...} ]),Jackson尝试把数组转成单个Person实例,自然抛出反序列化失败的异常。

解决方案

根据业务需求,有两种处理方式:

方式一:修正目标类型为HashMap<String, List<Person>>(推荐,完全匹配JSON结构)

直接把反序列化的目标类型改成键对应Person列表的HashMap,完全贴合返回的JSON结构,不需要额外处理:

// 直接指定正确的ParameterizedTypeReference,省去后续多余的convertValue操作
ResponseEntity<HashMap<String, List<Person>>> response = restTemplate.exchange(
        uriBuilder.toUriString(), HttpMethod.GET, httpEntity, 
        new ParameterizedTypeReference<HashMap<String, List<Person>>>() {}
);

HashMap<String, List<Person>> resultMap = response.getBody();
// 如果需要取出某个键下的第一个Person,比如scully对应的对象:
Person scully = resultMap.get("scully").get(0);
return resultMap;

方式二:自定义反序列化逻辑(适用于每个键下永远只有一个Person的场景)

如果业务上确定每个键对应的数组只会有一个Person对象,可以写个自定义反序列化器,自动取出数组第一个元素转成Person:

1. 编写自定义反序列化器

public class SinglePersonFromArrayDeserializer extends JsonDeserializer<Person> {
    @Override
    public Person deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        // 把JSON数组转成Person列表,取第一个元素返回
        List<Person> personList = p.readValueAs(new TypeReference<List<Person>>() {});
        return personList.isEmpty() ? null : personList.get(0);
    }
}

2. 配置RestTemplate使用自定义反序列化器

// 初始化带自定义反序列化器的ObjectMapper
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Person.class, new SinglePersonFromArrayDeserializer());
mapper.registerModule(module);

// 替换RestTemplate的消息转换器
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(mapper);
restTemplate.getMessageConverters().replaceAll(converter1 -> 
        converter1 instanceof MappingJackson2HttpMessageConverter ? converter : converter1
);

// 发起请求,此时可以直接用HashMap<String, Person>
ResponseEntity<HashMap<String, Person>> response = restTemplate.exchange(
        uriBuilder.toUriString(), HttpMethod.GET, httpEntity,
        new ParameterizedTypeReference<HashMap<String, Person>>() {}
);

HashMap<String, Person> resultMap = response.getBody();
return resultMap;
额外实体类修正建议

你的Person实体类里,@JsonProperty("BeginDate")和@JsonProperty("Absences")是大写开头,但JSON里对应的字段是beginDate和absences(小写开头),这会导致这些字段无法正确映射,需要修正注解:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
    @JsonProperty("beginDate")
    public String beginDate;
    public String endDate;
    @JsonProperty("absences")
    public List<Absence> absences;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:43:15