问题
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.assistingagriculture.entity.User` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
详细问题
笔者进行Android项目开发,
执行函数
return parseResponse1(response, User.class);
报错
parseResponse1实现代码
public static <T> T parseResponse1(String jsonData, Class<T> valueType) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonData, valueType);
}
User实体类
public class User {
private int id;
private String username;
private String password;
private String nickname;
private String email;
private String phone;
private String address;
private Timestamp createTime;
private String avatarUrl;
private String role;
// 全参构造方法、getter和setter方法
控制台详细报错如下
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.assistingagriculture.entity.User` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: at [Source: (String)"{"id":16,"username":"222","password":"b1c9f6ad0703828826e0bb01b281ef04","nickname":"甄姬好大","email":"2","phone":"17513216006","address":"2","createTime":"2022-02-26T14:10:14.000+00:00","avatarUrl":"http://localhost:9090/file/8d966b0e6cf84fe191a72a58b8293b23.png","role":"ROLE_TEACHER","courses":null,"stuCourses":null}
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: "; line: 1, column: 2]
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1764)
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1209)
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
2024-02-16 23:30:14.329 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:362)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:195)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.example.assistingagriculture.Utils.DataFormat.parseResponse1(DataFormat.java:152)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.example.assistingagriculture.Utils.DB.getUserById(DB.java:400)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.example.assistingagriculture.LoginActivity$GetUserTask.doInBackground(LoginActivity.java:290)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at com.example.assistingagriculture.LoginActivity$GetUserTask.doInBackground(LoginActivity.java:285)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at android.os.AsyncTask$3.call(AsyncTask.java:394)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2024-02-16 23:30:14.330 25335-25377/com.example.assistingagriculture W/System.err: at java.lang.Thread.run(Thread.java:923)
解决方案
解决方案一、
添加默认构造函数
public class User {
// 其他属性和方法
public User() {
// 默认构造函数
}
}
解决方案二、
使用注解来指定构造函数
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
private int id;
private String username;
private String password;
// 其他属性和方法
@JsonCreator
public User(@JsonProperty("id") int id,
@JsonProperty("username") String username,
@JsonProperty("password") String password,
// 其他属性
) {
this.id = id;
this.username = username;
this.password = password;
// 其他赋值
}
}
产生原因
问题产生的原因是在反序列化 JSON 数据时,Jackson 库无法找到合适的构造函数来实例化 User 类。具体来说,报错信息指出没有找到任何构造函数来构造 User 类的实例,也就是缺少默认构造函数或者没有通过注解指定构造函数。
解决原因
添加默认构造函数:通过在 User 类中添加一个无参数的默认构造函数,使得 Jackson 能够实例化该类的对象。默认构造函数不需要做任何具体操作,只需要存在即可。
使用注解来指定构造函数:可以使用 Jackson 的注解 @JsonCreator 和 @JsonProperty 来指定一个特定的构造函数,并告诉 Jackson 库如何使用这个构造函数来实例化对象。通过在构造函数上标注 @JsonCreator 注解,以及在构造函数参数上标注 @JsonProperty 注解来指定 JSON 字段与构造函数参数的映射关系。
通过以上两种方法之一,确保 Jackson 库能够正确地反序列化 JSON 数据并创建 User 对象,从而解决了报错问题。
总结
值得一提的是,为何此处默认构造函数不需要做任何具体操作,只需要存在即可。
这是由于使用Jackson库对类进行反序列化时,保类中存在一个无参数的默认构造函数,Jackson库才能够通过反射机制正确地实例化该类的对象。
此处对于Bean的操作,便是通过反射机制实现的
参考文献
产生原因与解释原因部分 部分内容参考chatgpt
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈