Android 不存在与默认构造类似的创建者):无法从对象值反序列化(没有基于委托或属性的创建者)
我试图使用改型和Jackson来使用API进行反序列化。我得到了onFailure错误Android 不存在与默认构造类似的创建者):无法从对象值反序列化(没有基于委托或属性的创建者),android,kotlin,jackson,retrofit2,Android,Kotlin,Jackson,Retrofit2,我试图使用改型和Jackson来使用API进行反序列化。我得到了onFailure错误像默认构造一样,没有创建者存在):无法从对象值反序列化(无委托或基于属性的创建者您需要使用jackson module kotlin反序列化到数据类。有关详细信息,请参阅 如果在某个数据类中未启用某个值,或者即使启用了该模块,当它使用的ObjectMapper未注册KotlinModule时,尝试将该值反序列化到该数据类中,则Jackson会给出上面的错误消息。例如,以下代码: data class TestD
像默认构造一样,没有创建者存在):无法从对象值反序列化(无委托或基于属性的创建者
您需要使用jackson module kotlin
反序列化到数据类。有关详细信息,请参阅
如果在某个数据类中未启用某个值,或者即使启用了该模块,当它使用的ObjectMapper
未注册KotlinModule
时,尝试将该值反序列化到该数据类中,则Jackson会给出上面的错误消息。例如,以下代码:
data class TestDataClass (val foo: String)
val jsonString = """{ "foo": "bar" }"""
val deserializedValue = ObjectMapper().readerFor(TestDataClass::class.java).readValue<TestDataClass>(jsonString)
如果您更改上面的代码并将ObjectMapper
替换为jacksonObjectMapper
(它只返回注册了KotlinModule
的正常ObjectMapper
),它就可以工作
val deserializedValue = jacksonObjectMapper().readerFor(TestDataClass::class.java).readValue<TestDataClass>(jsonString)
val deserializedValue=jacksonObjectMapper().readerFor(TestDataClass::class.java).readValue(jsonString)
我不确定Android方面的事情,但看起来您需要让系统使用
JacksonObject Mapper
来进行反序列化。很抱歉,只是懒散地提供解决方案而没有解释原因。现在我正在更新我的答案
原因:发生此错误的原因是jackson library
不知道如何创建没有空构造函数的模型,并且该模型包含的构造函数的参数没有使用@JsonProperty(“字段名称”)注释其参数
。默认情况下,如果未将构造函数添加到类中,java编译器将创建空构造函数
解决方案:
向模型中添加空构造函数
,或使用@JsonProperty(“字段名称”)注释构造函数参数
如果使用kotlin数据类
,则还可以使用@JsonProperty(“字段名称”)
进行注释或注册到ObjectMapper
您可以使用创建您的模型。我知道这是一篇旧文章,但对于任何使用改型的人来说,这可能是有用的
如果您使用的是翻新+Jackson+Kotlin+数据类,则需要:
将实现组:'com.fasterxml.jackson.module',名称:'jackson module kotlin',版本:'2.7.1-2'
添加到依赖项中,以便jackson可以反序列化到数据类中
建筑改造时,通过Kotlin Jackson映射器,以便改造使用正确的映射器,例如:
注意:如果未使用改装,@Jayson Minard有一个更通用的方法答案。我在这里搜索此错误:
No Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator
与改型无关,但是如果您使用Jackson,则通过向抛出错误的类添加默认构造函数来解决此错误。
更多信息:如果您使用的是http库,使用GsonObjectMapper
而不是JacksonObjectMapper
也可以
com.konghq
unirest对象映射器gson
2.3.17
我正在与Kotlin一起使用,并使用@ConstructorProperties解决了这个问题
data class MyResponse @ConstructorProperties("message", "count") constructor(
val message: String,
val count: Int
)
Jackson使用@ConstructorProperty。这也应该修复Lombok@数据。如果您在POJO模型上使用Lombok,请确保您有以下注释:
@Getter
@建筑商
@诺尔格构装师
@AllArgsConstructor
它可能会有所不同,但请确保@Getter
和尤其是@noargsconstuctor
我有一个类似的问题(使用Jackson、lombok、gradle)和一个没有参数构造函数的POJO-解决方案是添加
lombok.anyConstructor.addConstructorProperties=true
当您使用lombok builder时,您将看到上面的错误
@JsonDeserialize(builder = StationResponse.StationResponseBuilder.class)
public class StationResponse{
//define required properties
}
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPOJOBuilder(withPrefix = "")
public static class StationResponseBuilder {}
参考:使用Jackson作为提到的错误,该类没有默认构造函数
添加到entity类应该可以解决此问题。我可以借助@JacksonProperty
注释在Kotlin中解决此问题。上述情况的使用示例如下:
import com.fasterxml.jackson.annotation.JsonProperty
...
data class Station(
@JacksonProperty("repsol_id") val repsol_id: String,
@JacksonProperty("name") val name: String,
...
扩展Yoni Gibbs的答案,如果您在一个android项目中使用Jackson进行改造和配置序列化,那么您可以做这些事情,以便反序列化在kotlin的数据类中按预期工作
在构建渐变导入中:
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,则只需添加@noargsconstuctor
注释:
@AllArgsConstructor
@NoArgsConstructor
@Getter
@ToString
@EqualsAndHashCode
public class User {
private Long userId;
private String shortName;
}
我只想指出,这提供了一个更好的解释。
基本上,您可以将@Getter
和@NoArgConstructor
放在一起
或者让Lombok使用Lombok.config
文件重新生成@constructorproperty
或者使用-parameters
标志编译java项目,
或者让Jackson使用Lombok的@Builder
我有这个问题,我用下面的代码修复了它
@Configuration
open class JacksonMapper {
@Bean
open fun mapper(): ObjectMapper {
val mapper = ObjectMapper()
...
mapper.registerModule(KotlinModule())
return mapper
}
}
我的问题原因对我来说似乎非常罕见,不确定是否有其他人在相同条件下得到错误,我通过区分以前的提交找到了原因,给你:
通过我的build.gradle,我使用了这两个编译器选项,并注释了这一行,解决了这个问题
//compileJava.options.compilerArgs=['-Xlint:unchecked','-Xlint:deprecation']
如果您正在使用LOMBOK。
如果没有lombok.config文件,请创建该文件并添加此行
lombok.anyconstructor.addconstructorproperties=true
在下面的用例中遇到相同的错误
我尝试使用sprint启动(2.0.0快照版本)来达到Rest(放置映射)的终点,而没有在各自的bean中使用默认构造函数
但是,对于最新的Spring启动版本(2.4.1版本),相同的代码可以正常工作
因此,bean默认
@AllArgsConstructor
@NoArgsConstructor
@Getter
@ToString
@EqualsAndHashCode
public class User {
private Long userId;
private String shortName;
}
@Configuration
open class JacksonMapper {
@Bean
open fun mapper(): ObjectMapper {
val mapper = ObjectMapper()
...
mapper.registerModule(KotlinModule())
return mapper
}
}
lombok.anyconstructor.addconstructorproperties=true