如何在Kotlinx Serialization中自定义序列化器实现蛇形转驼形解析
自定义Kotlinx Serialization序列化器实现驼峰/蛇形字段名自动转换
完整实现代码
直接在数据类的伴生对象中实现自定义序列化逻辑,无需给每个字段加@SerialName注解:
import kotlinx.serialization.* import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonEncoder import kotlinx.serialization.json.jsonObject @Serializable data class User( val userId: Int, val userName: String, val userEmail: String ) { @Serializer(forClass = User::class) companion object : KSerializer<User> { // 复用官方默认序列化器,避免重复编写字段序列化逻辑 private val delegateSerializer = serializer<User>() override val descriptor: SerialDescriptor = delegateSerializer.descriptor override fun serialize(encoder: Encoder, value: User) { if (encoder is JsonEncoder) { // 先通过默认序列化器生成JSON,再把驼峰字段转成蛇形 val originalJson = delegateSerializer.serialize(encoder, value) val transformedJson = originalJson.jsonObject.mapKeys { (key, _) -> camelToSnake(key) } encoder.encodeJsonElement(transformedJson) } else { // 非JSON格式直接用默认序列化逻辑 delegateSerializer.serialize(encoder, value) } } override fun deserialize(decoder: Decoder): User { if (decoder is JsonDecoder) { // 先解码蛇形命名的JSON,把字段转成驼峰后再解析 val originalJson = decoder.decodeJsonElement().jsonObject val transformedJson = originalJson.mapKeys { (key, _) -> snakeToCamel(key) } return decoder.json.decodeFromJsonElement(delegateSerializer, transformedJson) } else { // 非JSON格式直接用默认反序列化逻辑 delegateSerializer.deserialize(decoder) } } // 驼峰转蛇形工具函数 private fun camelToSnake(name: String): String { return name.replace(Regex("([a-z0-9])([A-Z])"), "$1_$2").lowercase() } // 蛇形转驼峰工具函数 private fun snakeToCamel(name: String): String { return name.split("_") .joinToString("") { it.replaceFirstChar(Char::uppercase) } .replaceFirstChar(Char::lowercase) } } }
测试验证
运行以下代码确认序列化/反序列化效果:
fun main() { // 后端返回的蛇形命名JSON val snakeCaseJson = """{"user_id": 1, "user_name": "Jerry", "user_email": "jerry@example.com"}""" // 反序列化:蛇形字段自动转为驼峰属性 val user = kotlinx.serialization.json.Json.decodeFromString<User>(snakeCaseJson) println(user) // 输出:User(userId=1, userName=Jerry, userEmail=jerry@example.com) // 序列化:驼峰属性自动转为蛇形字段 val serializedJson = kotlinx.serialization.json.Json.encodeToString(user) println(serializedJson) // 输出:{"user_id":1,"user_name":"Jerry","user_email":"jerry@example.com"} }
关键逻辑说明
- 复用默认序列化器:通过
serializer<User>()获取官方实现,只做字段名转换,避免重复编写每个字段的序列化逻辑。 - 字段名双向转换:
- 序列化时,把数据类的驼峰属性名转为蛇形字段名
- 反序列化时,把JSON的蛇形字段名转为驼峰属性名
- 兼容非JSON场景:判断编码器/解码器类型,非JSON格式直接使用默认逻辑,保证通用性。
注意事项
- 若数据类包含嵌套的可序列化对象,嵌套类也需要配置相同的自定义序列化器,否则嵌套字段不会自动转换命名。
- 多个数据类需要该逻辑时,可将
camelToSnake和snakeToCamel抽离为顶层工具函数或单独工具类,避免代码重复。 - 确保项目已引入kotlinx serialization依赖,例如Gradle配置:
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

