如何解决Retrofit2 Kotlin中的INTERNAL SERVER ERROR问题?
我在Android Studio开发一款需要调用API的应用,选择Retrofit作为网络框架(社区活跃度比Volley更高)。目前遇到一个问题:登录接口在Postman中可以正常请求,但在Android端调用时无法正常工作,应用里的其他接口却完全正常。
已知所有参数需要以raw JSON形式传递,我已经配置了GSON转换器,理论上应该自动将数据类转换为原始JSON,且确认参数都已正确传入。
相关代码
登录接口调用代码
val body = LoginInformation("ken1","test",false) val call = ApiClient.apiService.postLogin(body) // Log.i("CHECK_RESPONSE",call.request().toString()) call.enqueue(object : Callback<AuthLogin> { override fun onResponse(call: Call<AuthLogin>, response: Response<AuthLogin>) { if (response.isSuccessful) { Log.i("CHECK_RESPONSE","onSuccess: ${response.body()}") } else { Log.i("CHECK_RESPONSE","onFailure: ${response.raw()}") } } override fun onFailure(call: Call<AuthLogin>, t: Throwable) { Log.i("CHECK_RESPONSE", "onError: ${t.message}") } })
ApiService定义
@POST("api/login") fun postLogin( @Body loginInformation: LoginInformation ): Call<AuthLogin>
数据类
LoginInformation.kt
data class LoginInformation( val user: String, val pass: String, val registrationMode: Boolean )
AuthLogin.kt
data class AuthLogin( val success: Boolean, val user_id: Int )
排查建议
核对字段名映射:
确认后端接口接收的参数名与数据类字段完全一致。例如如果后端期望的参数是registration_mode(下划线命名),而数据类里是registrationMode(驼峰命名),GSON默认不会自动转换,需要给字段添加@SerializedName注解:data class LoginInformation( val user: String, val pass: String, @SerializedName("registration_mode") val registrationMode: Boolean )打印实际请求内容:
添加HttpLoggingInterceptor到Retrofit客户端,打印完整的请求信息(包括Request Body、请求头),对比Postman中的请求内容,确认是否存在差异。
配置示例:val logging = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } val client = OkHttpClient.Builder() .addInterceptor(logging) .build() val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build()查看错误响应详情:
在onResponse的失败分支中,打印response.errorBody()?.string(),获取后端返回的具体错误信息,比如参数缺失、格式错误等:else { val errorMsg = response.errorBody()?.string() Log.i("CHECK_RESPONSE","onFailure: $errorMsg") }确认请求头:
检查Postman中的请求头是否包含Content-Type: application/json,Retrofit使用GSON转换器时会自动添加该头,但如果后端有特殊要求,可以手动指定:@POST("api/login") @Headers("Content-Type: application/json") fun postLogin( @Body loginInformation: LoginInformation ): Call<AuthLogin>
(附截图说明:Postman中发送的raw JSON包含user、pass、registrationMode三个字段,接口返回成功结果)
内容的提问来源于stack exchange,提问作者Majok

