Jackson反序列化器无默认构造函数:已试推荐方案仍报错求助
我懂你现在的困扰——明明已经照着之前的方案给自定义反序列化器加了无参构造,结果反序列化时还是弹出“没有无参构造”的错误,这种卡壳的感觉确实让人难受。咱们结合你给出的单元测试片段,一步步排查几个容易被忽略的点:
1. 确认自定义反序列化器的构造方法是否符合要求
首先,你的自定义反序列化器必须要有公共的无参构造方法,或者显式调用父类的构造。很多人会漏掉这一步,或者构造方法的访问修饰符不对(比如写成了private)。举个正确的示例:
public class ServiceDeserializer extends StdDeserializer<Service> { // 无参构造,必须是public public ServiceDeserializer() { super(Service.class); } // 或者带参数的构造,同时提供无参构造 public ServiceDeserializer(Class<?> vc) { super(vc); } @Override public Service deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 你的自定义反序列化逻辑 JsonNode node = p.getCodec().readTree(p); Service service = new Service(); service.setId(node.get("id").asText()); service.setTitle(node.get("title").asText()); // 其他字段赋值 return service; } }
2. 检查@JsonDeserialize注解的使用是否正确
如果你是用注解来指定反序列化器,一定要确保注解加对了位置,并且using属性指向的是正确的反序列化器类:
@JsonDeserialize(using = ServiceDeserializer.class) public class Service { private String id; private String title; private String description; private String type; // getter和setter }
要是注解加错了地方(比如加到了get方法上),或者类路径写错了,也会导致Jackson无法正确实例化反序列化器,进而抛出无参构造的错误。
3. 排查ObjectMapper的注册方式(如果手动注册)
如果你没有用注解,而是手动给ObjectMapper注册反序列化器,要注意必须直接传入反序列化器的实例,而不是Class对象。比如:
// 正确的方式:传入实例 ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(Service.class, new ServiceDeserializer()); mapper.registerModule(module); // 错误的方式:传入Class,Jackson会尝试用无参构造创建实例 // module.addDeserializer(Service.class, ServiceDeserializer.class);
如果用错误的方式注册,哪怕你的反序列化器有构造方法,也可能因为Jackson的内部逻辑触发异常。
4. 补全单元测试,验证序列化/反序列化全流程
你给出的测试代码没写完,建议补全后看看是否有流程上的问题。完整的测试应该是先序列化对象,再反序列化回来:
// 初始化对象 Service service = new Service(); service.setId("ID"); service.setTitle("Title"); service.setDescription("Description"); service.setType("Service"); // 序列化 ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(service); System.out.println("序列化后的JSON:" + json); // 先确认JSON格式是否正确 // 反序列化 try { Service deserializedService = mapper.readValue(json, Service.class); // 断言验证结果 } catch (JsonProcessingException e) { e.printStackTrace(); // 查看详细的错误栈,定位具体问题 }
打印出JSON字符串可以帮你确认是否有字段缺失或格式错误,而错误栈的详细信息也能帮你排查到底是构造方法的问题,还是反序列化逻辑里的其他错误。
5. 检查Jackson依赖版本是否冲突
最后,偶尔依赖版本冲突也会导致这类奇怪的问题。如果你的项目里同时引入了不同版本的jackson-databind、jackson-core或jackson-annotations,建议统一版本,比如用Maven BOM来管理:
<dependencyManagement> <dependencies> <dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>jackson-bom</artifactId> <version>2.15.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
内容的提问来源于stack exchange,提问作者Daniel Töws

