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

Jackson v3反序列化继承java.util.Properties的类时出现类型转换异常

Jackson v3升级后NodeProperties反序列化类型转换错误问题

问题背景

应用从Jackson v2升级到v3后,遭遇反序列化异常。自定义类NodeProperties继承自java.util.Properties,仅包含处理Properties的便利方法,无额外自定义字段:

public class NodeProperties extends Properties {
    ...
}

错误详情

读取包含内部数据结构的JSON文件时,抛出以下异常:

tools.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `my.application.connections.RESTConnection`, problem: Cannot cast java.util.Properties to my.application.utils.NodeProperties
 at [Source: (BufferedInputStream); line: 38, column: 2]

已排查方向

  • 给NodeProperties添加虚拟字段,问题未解决,排除无自定义字段导致的问题
  • 确认不属于多态场景,NodeProperties未继承抽象类或实现相关接口

核心疑问

为何Jackson v3会尝试创建父类Properties对象,而非实际需要的NodeProperties子类?


原因分析

Jackson v3对java.util.Properties的反序列化逻辑做了变更:v2版本中,遇到继承自Properties的子类时,Jackson会优先实例化子类;但v3中,PropertiesDeserializer被优化为默认返回Properties实例,忽略了子类类型——因为Properties本质是特殊的Map实现,Jackson默认将其当作普通Map处理,不会自动关联到子类类型。

解决方案

1. 为NodeProperties添加自定义反序列化器

实现一个自定义反序列化器,强制实例化NodeProperties并填充属性:

public class NodePropertiesDeserializer extends StdDeserializer<NodeProperties> {
    protected NodePropertiesDeserializer() {
        super(NodeProperties.class);
    }

    @Override
    public NodeProperties deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        NodeProperties props = new NodeProperties();
        JsonNode node = p.getCodec().readTree(p);
        if (node.isObject()) {
            for (Iterator<Map.Entry<String, JsonNode>> it = node.fields(); it.hasNext(); ) {
                Map.Entry<String, JsonNode> entry = it.next();
                props.setProperty(entry.getKey(), entry.getValue().asText());
            }
        }
        return props;
    }
}

通过注解将反序列化器绑定到NodeProperties类:

@JsonDeserialize(using = NodePropertiesDeserializer.class)
public class NodeProperties extends Properties {
    ...
}

2. 通过Jackson模块全局配置替换默认反序列化逻辑

如果需要全局生效,可通过SimpleModule替换默认的PropertiesDeserializer:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(NodeProperties.class, new NodePropertiesDeserializer());
mapper.registerModule(module);

3. 可选:启用大小写不敏感配置

若JSON中的键存在大小写差异,可添加此配置避免属性丢失:

mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

验证

应用上述任一配置后,Jackson会在反序列化时正确创建NodeProperties实例,避免类型转换错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 10:22:40