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

使用Jackson映射含数组类名的JSON时遇InvalidDefinitionException求助

解决Jackson映射Map<String, Class>时数组类型类名的反序列化问题

你遇到的问题是Jackson默认的Class反序列化器无法识别JVM内部的数组类型签名格式(比如[Ljava.lang.Double;),它只支持普通的全限定类名。不过好在我们可以通过自定义反序列化器来解决这个问题。

解决方案步骤:

  • 自定义一个JsonDeserializer<Class<?>>,利用Class.forName()方法(它本身支持解析JVM数组签名)来加载类。
  • 将这个自定义反序列化器注册到Jackson的ObjectMapper中,替换默认的Class反序列化逻辑。

完整代码示例:

首先是自定义反序列化器:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;

public class CustomClassDeserializer extends JsonDeserializer<Class<?>> {
    @Override
    public Class<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String className = p.getText();
        try {
            // Class.forName完全支持JVM的数组类型签名格式
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new IOException("Failed to load class: " + className, e);
        }
    }
}

然后是使用这个反序列化器的测试代码:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.util.Map;

public class JacksonClassMappingTest {
    public static void main(String[] args) throws Exception {
        String json = "{ \"keyA\": \"java.lang.Double\", \"keyB\": \"[Ljava.lang.Double;\" }";
        
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        // 注册自定义反序列化器
        module.addDeserializer(Class.class, new CustomClassDeserializer());
        objectMapper.registerModule(module);
        
        Map<String, Class<?>> result = objectMapper.readValue(json, Map.class);
        
        // 验证结果
        System.out.println("keyA对应的类:" + result.get("keyA"));
        System.out.println("keyB对应的类:" + result.get("keyB"));
        System.out.println("keyB是否为数组类型:" + result.get("keyB").isArray());
    }
}

代码说明:

  • Class.forName()方法本身就支持解析JVM的数组类型签名(比如[Ljava.lang.Double;代表Double[]类),所以自定义反序列化器的核心就是直接调用这个方法加载类。
  • 注册自定义反序列化器后,Jackson在处理Class类型的字段或值时,就会使用我们的逻辑,而不是默认的实现,这样就能正确解析数组类型的类名了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:23:14