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

Jackson ACCEPT_SINGLE_VALUE_AS_ARRAY与PolymorphicTypeValidator搭配失效 反序列化JPMML DefineFunction异常

解决方案

你的问题本质是两个不匹配:1. 入参JSON结构和JPMML模型的字段定义不匹配(Expression子类直接暴露在DefineFunction层级,没有被Expression字段包裹);2. 多余的全局多态配置覆盖了模型自带的多态注解,引发List反序列化冲突。不需要修改JPMML源码,也不需要写全量自定义反序列化器,按以下步骤处理即可:

步骤1:预处理JSON结构,补全Expression包裹层

因为JPMML的DefineFunction中表达式字段被定义为Expression,且多态配置为包装对象模式,需要把入参中直接放在DefineFunction下的表达式子类(比如示例中的MapValues)移动到Expression字段下:

// 先读取原始输入为JsonNode
ObjectMapper rawMapper = new ObjectMapper();
JsonNode rootNode = rawMapper.readTree(originalInputStr);
ObjectNode defineFunctionNode = (ObjectNode) rootNode;

// 所有Expression子类的名称列表,对应@JsonSubTypes里的name值
Set<String> expressionSubTypeNames = Set.of("Constant", "FieldRef", "NormContinuous", "NormDiscrete", 
        "Discretize", "MapValues", "TextIndex", "Apply", "Aggregate", "Lag");

// 查找属于Expression子类的字段
for (String fieldName : (Iterable<String>) defineFunctionNode::fieldNames) {
    if (expressionSubTypeNames.contains(fieldName)) {
        // 新建Expression包装节点
        ObjectNode expressionNode = rawMapper.createObjectNode();
        expressionNode.set(fieldName, defineFunctionNode.get(fieldName));
        defineFunctionNode.set("Expression", expressionNode);
        // 删除原有的子类字段
        defineFunctionNode.remove(fieldName);
        break;
    }
}

步骤2:配置ObjectMapper反序列化

只开单值转数组配置即可,不需要开启全局多态(JPMML模型的Expression字段已自带多态注解,全局多态会冲突):

ObjectMapper mapper = new ObjectMapper()
        .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

DefineFunction defineFunction = mapper.convertValue(defineFunctionNode, DefineFunction.class);

可选优化

如果需要处理大量同类结构,可以把上述JSON预处理逻辑封装为一个BeanDeserializerModifier,注册到ObjectMapper中,不需要每次手动处理节点,完全自动化处理所有符合JPMML结构的反序列化场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:57:01