You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin:修改LoginBody字段名,需保留新旧版本并支持切换

轻量解决方案:两种LoginBody字段格式切换实现

方案一:扩展函数+区分命名数据类(适合需显式区分类实例的场景)

首先为避免类名冲突,给新版数据类做命名区分:

// 原有驼峰字段版本
data class LoginBody(
    var username: String,
    var password: String,
    var deviceType: String,
    var deliveryPlatform: String,
    var osName: String,
    var deviceId: String
)

// 新版下划线字段版本,命名做区分
data class LoginBodySnakeCase(
    var username: String,
    var password: String,
    var device_type: String,
    var client_platform: String,
    var os_name: String,
    var device_id: String
)

通过扩展函数实现双向转换:

// 旧版转新版
fun LoginBody.toSnakeCaseVersion() = LoginBodySnakeCase(
    username = this.username,
    password = this.password,
    device_type = this.deviceType,
    client_platform = this.deliveryPlatform,
    os_name = this.osName,
    device_id = this.deviceId
)

// 新版转旧版(如需回退兼容)
fun LoginBodySnakeCase.toCamelCaseVersion() = LoginBody(
    username = this.username,
    password = this.password,
    deviceType = this.device_type,
    deliveryPlatform = this.client_platform,
    osName = this.os_name,
    deviceId = this.device_id
)

最后根据启动场景的开关决定使用哪个版本:

// 全局开关,可从启动参数、环境变量或配置文件读取
val useSnakeCaseLogin = false // true则用新版,false用旧版

// 使用示例
fun submitLogin(originalBody: LoginBody) {
    val requestBody = if (useSnakeCaseLogin) {
        originalBody.toSnakeCaseVersion()
    } else {
        originalBody
    }
    // 后续将requestBody传入接口请求
}

方案二:序列化策略切换(无需新增类,更轻量,适合接口参数序列化场景)

如果你的场景是和后端交互时需要不同的字段名格式,推荐直接通过序列化框架的配置实现,不需要新增数据类。以Gson为例:

步骤1:给原有LoginBody字段添加多序列化别名

data class LoginBody(
    var username: String,
    var password: String,
    @SerializedName(value = "deviceType", alternate = ["device_type"])
    var deviceType: String,
    @SerializedName(value = "deliveryPlatform", alternate = ["client_platform"])
    var deliveryPlatform: String,
    @SerializedName(value = "osName", alternate = ["os_name"])
    var osName: String,
    @SerializedName(value = "deviceId", alternate = ["device_id"])
    var deviceId: String
)

步骤2:创建不同序列化策略的Gson实例

// 旧版:使用驼峰字段名序列化
val gsonCamel = GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
    .create()

// 新版:自动将驼峰字段转为下划线格式
val gsonSnake = GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create()

步骤3:根据场景切换Gson实例

val useSnakeCase = true // 启动场景决定该值

// 序列化示例
fun serializeLoginRequest(body: LoginBody): String {
    return if (useSnakeCase) {
        gsonSnake.toJson(body)
    } else {
        gsonCamel.toJson(body)
    }
}

// 反序列化示例(兼容两种格式的响应)
fun deserializeLoginResponse(json: String): LoginBody {
    // 因为添加了alternate注解,两种格式的响应都能正常解析
    return gsonCamel.fromJson(json, LoginBody::class.java)
}

这个方案不需要修改现有大量使用LoginBody的业务代码,仅在序列化/反序列化环节切换配置,完全满足轻量需求,且旧版本废弃后只需移除旧的Gson实例和注解即可。

内容的提问来源于stack exchange,提问作者Kratos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:25:50