使用Kotlin默认值的Jackson反序列化失败

时间:2019-01-06 12:12:42

标签: android kotlin jackson proguard

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

我为此使用Jackson Module Kotlin库。

我有一些带有默认值的数据类,这些值用Java表示为原始值,因此在不进行空检查的情况下访问它不会崩溃。

这一切在调试模式下都能很好地工作,但是当我在启用了proguard的发行版上运行时,未设置默认值,并且这些值均为null,从而导致我的应用程序在从Java(假定原始)访问它们时崩溃。

我试图添加在网上找到的所有职业警卫规则:),但没有成功。

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

谢谢

数据类示例

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

Retrofit和Jackson初始化

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>;
}

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

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

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