如何将Kotlin对象数组转换为保留访问键名的指定JSON格式用于Retrofit请求
实现方案
你需要的JSON格式本质是将列表对象扁平化处理为特殊格式的键值对,有两种常用实现方案,均可适配Retrofit请求:
方案1:手动构造Map(适合字段少、使用场景少的情况)
直接遍历列表拼接指定格式的key,生成HashMap后直接作为请求体传入Retrofit即可。
转换代码:
// 先补全RailPoint类的字段类型,避免序列化异常 class RailPoint( var railPointId: Int, var startTime: String, var endTime: String ) fun convertRailsToRequestMap(rails: List<RailPoint>): Map<String, Any?> { val requestMap = hashMapOf<String, Any?>() rails.forEachIndexed { index, point -> requestMap["railPoint[$index][railPointId]"] = point.railPointId requestMap["railPoint[$index][startTime]"] = point.startTime requestMap["railPoint[$index][endTime]"] = point.endTime } return requestMap }
Retrofit接口定义:
interface ApiService { @POST("你的接口地址") suspend fun submitRailPoints(@Body requestBody: Map<String, Any?>): Response<你的返回数据类型> }
调用示例:
val rails = arrayListOf(RailPoint(5, "", "2021-10-19 07:37:19"), RailPoint(1, "2021-10-19 07:33:37", "2021-10-19 07:35:20")) val api = retrofit.create(ApiService::class.java) api.submitRailPoints(convertRailsToRequestMap(rails))
方案2:自定义Gson序列化器(适合字段多、多处使用的场景)
如果项目用Gson作为Retrofit的序列化工具,可以自定义序列化规则,无需每次手动构造Map,使用更便捷。
自定义序列化器代码:
import com.google.gson.JsonSerializer import com.google.gson.JsonElement import com.google.gson.JsonSerializationContext import java.lang.reflect.Type class RailListSerializer : JsonSerializer<List<RailPoint>> { override fun serialize( src: List<RailPoint>?, typeOfSrc: Type?, context: JsonSerializationContext? ): JsonElement { val jsonObj = com.google.gson.JsonObject() src?.forEachIndexed { index, point -> jsonObj.addProperty("railPoint[$index][railPointId]", point.railPointId) jsonObj.addProperty("railPoint[$index][startTime]", point.startTime) jsonObj.addProperty("railPoint[$index][endTime]", point.endTime) } return jsonObj } }
配置Gson和Retrofit:
import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory // 注册自定义序列化器 val gson = GsonBuilder() .registerTypeAdapter(object : TypeToken<List<RailPoint>>() {}.type, RailListSerializer()) .create() // 配置到Retrofit val retrofit = Retrofit.Builder() .baseUrl("你的服务BaseUrl") .addConverterFactory(GsonConverterFactory.create(gson)) .build()
Retrofit接口定义:
interface ApiService { @POST("你的接口地址") suspend fun submitRailPoints(@Body railList: List<RailPoint>): Response<你的返回数据类型> }
调用示例:
val rails = arrayListOf(RailPoint(5, "", "2021-10-19 07:37:19"), RailPoint(1, "2021-10-19 07:33:37", "2021-10-19 07:35:20")) val api = retrofit.create(ApiService::class.java) api.submitRailPoints(rails)
验证结果
两种方案生成的JSON均和你要求的格式完全一致,如果后续RailPoint新增字段,同步更新对应转换逻辑里的key拼接规则即可。
提示:如果接口不允许出现null值,建议给RailPoint的字段设置默认空值,避免序列化时出现非预期的null字段
内容的提问来源于stack exchange,提问作者Rajnikant B
相关产品推荐
相关产品推荐

