Kotlin Retrofit2如何实现携带raw JSON请求体的登录接口调用
Retrofit raw JSON请求体配置错误解决方案
错误原因
你当前的写法出现错误有两个核心原因:
- 传入
org.json.JSONObject作为@Body参数:你配置的GsonConverterFactory无法正确序列化该类型对象,会把JSONObject内部存储结构一起序列化,最终生成的请求体不符合接口要求的格式。 - 直接传入String作为
@Body参数:GsonConverter会对String类型做JSON序列化处理,自动给字符串套双层双引号、转义内部特殊字符,导致请求体格式错误。
推荐解决方案:定义请求数据类(类型安全,易维护)
这是Android Retrofit开发的标准实现方式,不需要手动拼接JSON。
- 首先定义登录请求的参数数据类
data class SignInRequest( val email: String, val password: String )
- 修改Api接口中的登录方法参数类型
@POST("signin") suspend fun signIn( @Body request: SignInRequest ): SignInResponse
- 修改ViewModel中的调用逻辑
fun signIn(email: String, password: String) { val requestParam = SignInRequest(email = email, password = password) viewModelScope.launch { try { signInResponse.value = api.signIn(requestParam) } catch (e: Exception) { Log.d(TAG, "signInError: $e") } } }
Retrofit会自动通过Gson把SignInRequest对象序列化为符合要求的raw JSON格式请求体。
可选方案:手动构造RequestBody
如果你确实需要手动拼接JSON字符串,可以直接构造RequestBody绕过Gson序列化:
- 修改Api接口参数类型
@POST("signin") suspend fun signIn( @Body body: RequestBody ): SignInResponse
- ViewModel中构造RequestBody传入
fun signIn(email: String, password: String) { // 手动拼接JSON字符串,也可以用JSONObject拼接后调用toString()获取 val jsonContent = """ { "email": "$email", "password": "$password" } """.trimIndent() val requestBody = jsonContent.toRequestBody("application/json; charset=utf-8".toMediaType()) viewModelScope.launch { try { signInResponse.value = api.signIn(requestBody) } catch (e: Exception) { Log.d(TAG, "signInError: $e") } } }
其他排查点
- 确认
AndroidManifest.xml中已添加网络权限<uses-permission android:name="android.permission.INTERNET" /> - 确认Retrofit配置的
BASE_URL后缀带斜杠,比如https://your-domain.com/api/,避免路径拼接错误 - 确认
SignInResponse类的字段结构和接口返回的JSON结构完全匹配,必要时添加@SerializedName注解做字段映射
内容的提问来源于stack exchange,提问作者Alun Paranggi Wicaksono
相关产品推荐
相关产品推荐

