如何接收并序列化服务器发送的二维字节数组?
Kotlin序列化二维字节数组失败的解决方案
问题描述
服务器返回的JSON包含二维字节数组(示例:[[102, 222, 111], [92, 22, 111], [142, 122, 32]]),需序列化后处理。iOS中可直接通过Data(bytes)完成转换,但使用kotlinx.serialization定义如下数据类时:
import kotlinx.serialization.Serializable @Serializable data class ServerResponse( val fileRaw: List<List<Byte>>? )
抛出错误:Unexpected JSON token at offset 1829: Failed to parse 'byte'。
原因分析
kotlinx.serialization对Byte类型的默认解析会严格校验取值范围(-128~127),而JSON中的数值(如222、142)超出了这个范围,导致解析失败。
解决方案
方案1:改用Int列表接收后转换
将数据类中的类型改为List<List<Int>>,反序列化后手动将Int转换为Byte(超出Byte范围的数值会自动截断,与iOS的Data(bytes)行为一致):
import kotlinx.serialization.Serializable @Serializable data class ServerResponse( val fileRaw: List<List<Int>>? ) // 转换为字节数组的逻辑 val response: ServerResponse = // 反序列化后的对象 val byteArray = response.fileRaw?.flatMap { intList -> intList.map { it.toByte() } }?.toByteArray()
方案2:自定义Byte序列化器
为Byte类型编写自定义序列化器,跳过取值范围校验,直接将JSON中的Int数值解析为Byte:
import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder // 自定义不校验范围的Byte序列化器 object UncheckedByteSerializer : KSerializer<Byte> { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UncheckedByte", PrimitiveKind.INT) override fun serialize(encoder: Encoder, value: Byte) { encoder.encodeInt(value.toInt()) } override fun deserialize(decoder: Decoder): Byte { return decoder.decodeInt().toByte() } } // 在数据类中使用自定义序列化器 @Serializable data class ServerResponse( @Serializable(with = UncheckedByteSerializer::class) val fileRaw: List<List<Byte>>? )
两种方案均可解决解析问题:方案1实现简单,无需额外代码;方案2保留了Byte类型的语义,更贴合业务逻辑。
内容的提问来源于stack exchange,提问作者WiseEye
相关产品推荐
相关产品推荐

