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

Spring Boot中RestTemplate反序列化Currency实体报错排查

问题原因及排查方案

核心问题分析

你遇到的反序列化错误,本质是服务端返回的JSON结构、类型与客户端Jackson预期的反序列化逻辑不匹配,具体可能有以下几种情况:

  • 客户端类定义与实际返回类型不符:
    虽然你说客户端Currency类的transferRate是Map<String, Object>,但可能实际代码中写错了泛型(比如误写成Map<String, double>)。如果服务端返回的JSON里,transferRate的某个值是字符串类型(比如数据库里存的是{"USD":"6.9"}),或者是整数类型(比如{"GBP":8}),Jackson在将其反序列化为double类型时就会抛出这个错误。

  • JpaConverterJson序列化导致JSON结构异常:
    服务端的JpaConverterJson如果没有正确实现Map到JSON的转换,可能会把Map序列化成嵌套结构(比如{"entries":[{"key":"USD","value":6.9}]})而非标准的扁平键值对。客户端Jackson试图把这种嵌套结构反序列化为Map<String, Object>时,会将内部的value字段识别为Object,而如果后续代码隐含要求将其转为double,就会触发反序列化错误。

  • 数据库存储的JSON数据格式错误:
    部分transferRate的JSON数据可能不是标准的键值对Map(比如存成了单个数值6.9、字符串"6.9"或者数组[6.9,7.5]),服务端读取后直接返回,客户端Jackson无法将这些非Map结构反序列化为Map<String, Object>,错误提示被包装为“无法从Object值反序列化为double”。

  • Jackson反序列化配置冲突:
    客户端RestTemplate配置的Jackson ObjectMapper如果开启了强制数值转换的特性(比如DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY或自定义类型转换器),可能会错误地将Map中的单个Object值强制转换为double类型,导致匹配失败。

排查与解决步骤

  1. 查看服务端返回的原始JSON:
    通过Postman或浏览器直接调用接口,确认transferRate字段的结构是否为标准键值对(比如{"USD":6.9, "EUR":7.5}),是否存在非数值类型的值或异常结构。

  2. 核对客户端Currency类定义:
    确认transferRate字段的泛型确实是Map<String, Object>,没有误写为Map<String, double>或其他类型。

  3. 检查服务端JpaConverterJson实现:
    确保转换器正确将Map序列化为扁平JSON键值对,没有额外嵌套。比如正确的转换逻辑应该是:

    @Converter(autoApply = true)
    public class MapConverter implements AttributeConverter<Map<String, Object>, String> {
        private final ObjectMapper objectMapper = new ObjectMapper();
    
        @Override
        public String convertToDatabaseColumn(Map<String, Object> attribute) {
            try {
                return objectMapper.writeValueAsString(attribute);
            } catch (JsonProcessingException e) {
                throw new RuntimeException("Failed to serialize map to JSON", e);
            }
        }
    
        @Override
        public Map<String, Object> convertToEntityAttribute(String dbData) {
            try {
                return objectMapper.readValue(dbData, new TypeReference<Map<String, Object>>() {});
            } catch (JsonProcessingException e) {
                throw new RuntimeException("Failed to deserialize JSON to map", e);
            }
        }
    }
    
  4. 检查数据库中的JSON数据:
    直接查询数据库,查看transferRate字段的存储内容,清理或修复格式异常的数据。

  5. 调整Jackson配置:
    客户端RestTemplate的ObjectMapper可以添加配置,允许灵活处理数值类型:

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
    objectMapper.configure(DeserializationFeature.ACCEPT_ANY_MAP_KEY, true);
    restTemplate.setMessageConverters(Collections.singletonList(new MappingJackson2HttpMessageConverter(objectMapper)));
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:36:25