kotlin - 需要在 Kotlin 中将 Any 序列化为 base64 字符串
问题描述
我在 Kotlin 中有以下代码,我的目标是使用它将任何实例转换为 base64 编码的字符串。同样不起作用,它会引发以下错误:
Serializer for class 'Any' is not found.\nMark the class as @Serializable or provide the serializer explicitly
我怎样才能解决这个问题?
class SerializerAdapter: SerializerPort {
private val logger: Logger = LoggerFactory.getLogger(javaClass.simpleName)
override fun toBase64(input: Any): String {
try {
val jsonString = Json.encodeToString(input)
return Base64.getEncoder().encodeToString(jsonString.toByteArray())
}catch (ex: Exception) {
logger.error("[BASE64 Error] error converting json object to base64 encoded string: ${ex.stackTraceToString()}")
}finally {
return ""
}
}
}
解决方案
序列化Any
并不像听起来那么简单。序列化框架必须知道要序列化的数据类型。它可以使用编译类型(Any
在您的情况下)或运行时类型(提供给的实际类型toBase64()
)。这两种选择都有其缺点。由于类型擦除,运行时类型不完整,因此例如List<Int>
和List<String>
是相同的。另一方面,编译时类型可能会完全丢失,例如在泛型中或在您的情况下。
Kotlin 序列化通常更喜欢编译类型,特别是因为reified
参数使它们更有用。可惜我们这里不能使用reified
,因为toBase64()
是虚函数,所以不能内联。
我的建议是更改此函数的签名以额外接收KType
提供的数据,然后创建内联函数以方便使用:
override fun toBase64(input: Any, type: KType): String {
try {
val serializer = Json.serializersModule.serializer(type)
val jsonString = Json.encodeToString(serializer, input)
...
}
}
@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T> SerializerPort.toBase64(input: Any) = toBase64(input, typeOf<T>())
或者,我们可以使用运行时类型进行序列化,但请注意我之前提到的问题 - 它可能不适用于泛型。
val serializer = Json.serializersModule.serializer(input::class.starProjectedType)
val jsonString = Json.encodeToString(serializer, input)
推荐阅读
- microsoft-graph-api - Graph API 无法在手机中进行身份验证
- javascript - 单击时更改 H3 值,但该值出现
- python - 为什么带有 ThreadPoolExecutor 的 Dynesty 多处理不使用所有内核?
- php - 使用选定用户的 Mysql 数据创建 PHP 表/图表
- python - 从边缘计算缺失的像素值
- python - 为 jinja2 模板值设置空变量
- javascript - javascript如何向对象添加函数
- vba - 如何在Excel中合并具有相同数据的相邻列?
- ios - Swift 4 BLE 中央管理器 didConnect
- javascript - 抛出嵌套的异步函数(javascript)