使用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
相关产品推荐
相关产品推荐

