找不到类“...”的序列化程序。将类标记为 @Serializable 或显式提供序列化器

Vic*_*lyk 36 kotlin ktor kotlinx.serialization

您好,我在 kotlin 中类序列化时遇到问题

构建.gradl.kt

...
plugins {
    application
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.serialization").version("1.6.21")
}
...
depenedancies{
...
    implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
} 
Run Code Online (Sandbox Code Playgroud)

响应.kt

import kotlinx.serialization.*
...
interface BaseResponse<T>

@Serializable
data class PaginatedResponse<T>(
    val prev: Int?,
    val next: Int?,
    val totalCount: Int = 0,
    val totalPages: Int = 0,
    val data: T? = null,
    val message: String? = null
) : BaseResponse<T>
Run Code Online (Sandbox Code Playgroud)

用法

...
  return PaginatedResponse<List<User>>(
                prev,
                next,
                totalCount,
                totalPages,
                users
            )
Run Code Online (Sandbox Code Playgroud)

我传递的数据看起来很健康 在此输入图像描述 接下来是返回时抛出的错误

kotlinx.serialization.SerializationException: Serializer for class 'PaginatedResponse' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
Run Code Online (Sandbox Code Playgroud)

执行 call.respond(User(...)) 不会引发任何错误

因此,如果我删除通用并使 PaginatedResponse 非通用,它将起作用,但不再可重用

@Serializable
data class PaginatedResponse(
    val prev: Int?,
    val next: Int?,
    val totalCount: Long = 0,
    val totalPages: Long = 0,
    val data: List<User>? = null,
    val message: String? = null
) : BaseResponse<User>
Run Code Online (Sandbox Code Playgroud)

Jer*_*der 71

阅读一些文档后,我发现我的案例中的错误主要是由于我的两个错误配置造成的:

首先:我需要在应用程序和项目级别的 gradle 中添加插件,我按如下方式解决了这个问题:在gradle.project中添加下一行: id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.21'

如下图所示: gradle.模块

之后,在gradle.app 的插件块中添加下一行:id 'kotlinx-serialization'

如下图所示: gradle.app

其次,问题是当类在运行时序列化时,混淆器会产生冲突,为此我必须在文件中添加几行proguard-rules.pro 项目树

并将以下行添加到文件中:

### your config ....

# Keep `Companion` object fields of serializable classes.
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
   static <1>$Companion Companion;
}

# Keep `serializer()` on companion objects (both default and named) of serializable classes.
-if @kotlinx.serialization.Serializable class ** {
   static **$* *;
}
-keepclassmembers class <2>$<3> {
   kotlinx.serialization.KSerializer serializer(...);
}

# Keep `INSTANCE.serializer()` of serializable objects.
-if @kotlinx.serialization.Serializable class ** {
   public static ** INSTANCE;
}
-keepclassmembers class <1> {
   public static <1> INSTANCE;
   kotlinx.serialization.KSerializer serializer(...);
}

# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
Run Code Online (Sandbox Code Playgroud)

如下图所示: 文件 proguard-rules.pro

我终于同步了 gradle,再次编译,一切正常。

参考文档:https://github.com/Kotlin/kotlinx.serialization#gradle-with-plugins-block

  • 注意:ProGuard 规则现在[作为库的一部分包含](https://github.com/Kotlin/kotlinx.serialization/blob/master/rules/common.pro)(首先包含在 [1.5.0-RC] 中) (https://github.com/Kotlin/kotlinx.serialization/releases/tag/v1.5.0-RC)),如[自述文件](https://github.com/Kotlin/kotlinx.serialization#android )。(请注意,命名伴随对象不包括在内,并且仍然需要如上所述的额外配置) (3认同)
  • 这有很大帮助。将 `id 'kotlinx-serialization'` 添加到为我修复的应用程序模块的 build.gradle 文件中。 (2认同)