我正在尝试使用Retrofit和Jackson来反序列化一个API。我得到的onFailure错误没有创造者,像默认构造,存在):不能从对象值反序列化(没有委托或基于属性的创造者。
当前回答
Bek的答案是正确的。
但如果有人试图在restcontroller中使用不可变类,即他们正在使用lombok的@value,那么你需要添加lombok. anyconstructor . addconstructorproperties =true
您可以创建一个名为lombok的文件。在根文件pom.xml所在的相同位置进行配置,并将这一行添加到文件中
https://stackoverflow.com/a/56022839/6700081
其他回答
对于我们没有默认构造的类,例如当使用不可变对象时,Jackson默认情况下将不能将JSON反序列化为对象。 我们可以使用一些注释来解决这个问题,比如@JsonCreator,它可以帮助Jackson知道如何反序列化给定的JSON。
示例代码如下所示:
package com.test.hello;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Payment {
private final Card card;
private final Amount amount;
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public Payment(@JsonProperty("card") Card card, @JsonProperty("amount") Amount amount) {
this.card = card;
this.amount = amount;
}
public Card getCard() {
return card;
}
public Amount getAmount() {
return amount;
}
}
如果您在POJO模型上使用Lombok,请确保您有这些注释:
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
它可以有所不同,但要确保@Getter,特别是@NoArgsConstructor。
扩展Yoni Gibbs的回答,如果你在一个android项目中使用改装和配置序列化与Jackson,你可以做这些事情,以便反序列化工作预期与kotlin的数据类。
在你的build gradle导入中:
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.11.+"
然后,你的改造实施:
val serverURL = "http://localhost:8080/api/v1"
val objectMapper = ObjectMapper()
objectMapper.registerModule(KotlinModule())
//Only if you are using Java 8's Time API too, require jackson-datatype-jsr310
objectMapper.registerModule(JavaTimeModule())
Retrofit.Builder()
.baseUrl(serverURL)
.client(
OkHttpClient.Builder()
.readTimeout(1, TimeUnit.MINUTES)//No mandatory
.connectTimeout(1, TimeUnit.MINUTES)//No mandatory
.addInterceptor(UnauthorizedHandler())//No mandatory
.build())
.addConverterFactory(
JacksonConverterFactory.create(objectMapper)
)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
数据类:
@JsonIgnoreProperties(ignoreUnknown = true)
data class Task(val id: Int,
val name: String,
@JsonSerialize(using = LocalDateTimeSerializer::class)
@JsonDeserialize(using = LocalDateTimeDeserializer::class)
val specificDate: LocalDateTime?,
var completed: Boolean,
val archived: Boolean,
val taskListId: UUID?
使用Lombok时要小心,尤其是@Builder。
解决这个问题的方法是:
@JsonDeserialize(builder = X.XBuilder.class)
class X{
@JsonPOJOBuilder(withPrefix = "")
public static class XBuilder{
}
}
我希望它能让你的生活更轻松
Bek的答案是正确的。
但如果有人试图在restcontroller中使用不可变类,即他们正在使用lombok的@value,那么你需要添加lombok. anyconstructor . addconstructorproperties =true
您可以创建一个名为lombok的文件。在根文件pom.xml所在的相同位置进行配置,并将这一行添加到文件中
https://stackoverflow.com/a/56022839/6700081
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- Kotlin中惯用的登录方式
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 将JsonNode转换为POJO
- 杰克逊克服下划线,支持骆驼案