【问题标题】:Jackson deserialization with Kotlin default value fail使用 Kotlin 默认值的 Jackson 反序列化失败
【发布时间】:2019-06-01 08:23:15
【问题描述】:

我正在使用 Jackson 反序列化来自 Retrofit 的 Json 响应。

我为此使用 Jackson Module Kotlin 库。

我的数据类对于 Java 表示为基元的某些值具有默认值,因此在没有空检查的情况下访问它时不会崩溃。

这在debug 模式下一切正常,但是当我在release 上运行并启用proguard 时,未设置默认值并且这些值为空,导致我的应用程序在假设原语从Java 访问它们时崩溃。

我已尝试添加可以在网上找到的所有 proguard 规则,但没有成功。

如果有人有任何想法,请分享。

谢谢

数据类示例

data class RideTask(@JsonProperty(RiderFrontendConsts.PARAM_LOCATION)
                    val location: UserVisibleLocation?,

                    @JsonProperty(RiderFrontendConsts.PARAM_ETA_TS)
                    val etaTime: Double?,

                    @JsonProperty(RiderFrontendConsts.PARAM_TIME_TO_COMPLETION)
                    val timeToCompletion: Double?,

                    @JsonProperty(RiderFrontendConsts.PARAM_ETA_DESCRIPTION)
                    val etaDescription: String?,

                    @JsonInclude(JsonInclude.Include.NON_NULL)
                    @JsonProperty(RiderFrontendConsts.PARAM_INTERNAL_ETA_TS)
                    val internalEta: Long? = 0,

                    @JsonProperty(RiderFrontendConsts.PARAM_ETA_DESCRIPTION_LIST)
                    val etaDescriptionList: List<String>?,

                    @JsonProperty(RiderFrontendConsts.PARAM_DESCRIPTION_PREFIX)
                    val descriptionPrefix: String?,

                    @JsonProperty(RiderFrontendConsts.PARAM_WALKING_DISTANCE_DESCRIPTION)
                    val walkingDistanceDescription: String?,

                    @JsonProperty(RiderFrontendConsts.PARAM_WALKING_DISTANCE_IN_METERS)
                    val walkingDistanceInMeters: Int? = 0)
    : Serializable

改造和杰克逊初始化

private Retrofit getRetrofit() {
    LOGGER.debug("prepare retrofit");
    return new Retrofit.Builder()
            .client(getHttpClient(RiderFrontendConsts.DEFAULT_TIMEOUT_IN_MILLIS))
            .baseUrl(SettingsManager.getInstance(Application.getInstance()).getServerBaseUrl())
            .addConverterFactory(JacksonConverterFactory.create(getObjectMapper()))
            .callbackExecutor(Executors.newCachedThreadPool())
            .build();
}

private static ObjectMapper getObjectMapper() {
    LOGGER.debug("prepare object mapper");
    return ExtensionsKt.jacksonObjectMapper()
            .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
            .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
            .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
            .enable(SerializationFeature.WRITE_ENUMS_USING_INDEX)
            .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
            .setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY)
            .setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
            .setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
            .setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);
}

相关的职业守卫规则

#parsers
-keep class com.fasterxml.jackson.annotation.** { *; }
-dontwarn com.fasterxml.jackson.databind.**

# Kotlin
-keep class kotlin.Metadata { *; }
-keepclassmembers public class via.rider.frontend.** {
    public synthetic <methods>;
}

【问题讨论】:

  • 我来自后端领域,我没有任何类型的 proguard,但为了让 Jackson 使用 Kotlin 的东西,我必须将 jackson-module-kotlin 添加到类路径并调用 @ 987654328@ 从那里扩展功能。希望这会有所帮助。
  • 谢谢@oleg,我已经在使用它了。这绝对是专业后卫的东西,因为没有它它也能正常工作

标签: android kotlin jackson proguard


【解决方案1】:

认为问题在于您必须添加规则才能保留字段名称,例如

-keep class your.package.model.** { <fields>; }

【讨论】:

    【解决方案2】:

    您需要保留数据类文件(RideTask 的包 - 我的示例假设 RideTask 所在的 dto 包),如下所示:

    -keep,includedescriptorclasses class via.rider.dto.** { *; }
    

    如果这不能为您解决问题,请发布带有解析错误的 logcat。

    【讨论】:

    • 对于它的价值,并且看到 OP 没有回应,我遇到了完全相同的问题,这并不能解决我的问题。我得到以下异常:kotlin.reflect.jvm.internal.KotlinReflectionInternalError: This callable does not support a default call: public constructor MyConstructor ...
    • 看起来这可能有一个解决方法:github.com/FasterXML/jackson-module-kotlin/issues/130
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2018-07-15
    • 2014-07-16
    • 1970-01-01
    • 2022-10-15
    • 2018-12-26
    相关资源
    最近更新 更多