改造 POST 响应转换失败,无影无踪
Posted
技术标签:
【中文标题】改造 POST 响应转换失败,无影无踪【英文标题】:Retrofit POST response conversion fails without a trace 【发布时间】:2021-06-21 04:10:15 【问题描述】:我正在为一家使用 MVVM 和简洁架构的公司构建应用程序,因此我创建了 3 个模块,应用程序模块(表示层)、数据模块(数据层)和域模块(域/交互器层) .现在,在我的数据模块中,我使用 Retrofit 和 Gson 将我从登录 POST 请求接收到的 JSON 自动转换为我的名为 NetUserSession 的 kotlin 数据类,如下所示。我遇到的问题是日志拦截器通常会打印带有数据的响应,但是response.body()
返回一个空值的空 NetUserSession 对象,这让我认为由于某种原因没有发生自动转换。有人可以告诉我我在这里做错了什么吗?
KoinModules:
val domainModule = module
single<LoginRepository> LoginRepositoryImpl(get())
single LoginUseCase(get())
val presentationModule = module
viewModel LoginViewModel(get(),get())
val dataModule = module
single ApiServiceImpl().getApiService()
single LoginRepositoryImpl(get())
API 接口和改造:
interface ApiService
@POST("Login")
fun getLoginResult(@Body netUser: NetUser) : Call<NetUserSession>
@GET("Books")
fun getBooks(@Header("Authorization") token:String) : Call<List<NetBook>>
class ApiServiceImpl
fun getApiService(): ApiService
val logging = HttpLoggingInterceptor()
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
//TODO:SP Remove the interceptor code when done debugging
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(logging)
.build()
val retrofit = Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
// tell retrofit to implement the interface of our api
return retrofit.create(ApiService::class.java)
NetUserSession:
data class NetUserSession(
@SerializedName("expires_in")
val expires_in: Int,
@SerializedName("token_type")
val token_type: String,
@SerializedName("refresh_token")
val refresh_token: String,
@SerializedName("access_token")
val access_token: String
)
fun toUserSession(): UserSession = UserSession(
expiresIn = expires_in,
tokenType = token_type,
refreshToken = refresh_token,
accessToken = access_token
)
域中的用户会话:
data class UserSession(
val expiresIn:Int,
val tokenType:String,
val refreshToken:String,
val accessToken:String
)
发生错误的LoginRepositoryImpl:
class LoginRepositoryImpl(private val apiService: ApiService) : LoginRepository
override suspend fun login(username:String,password:String): UserSession? = withContext(Dispatchers.IO)
val response = apiService.getLoginResult(NetUser(username,password)).awaitResponse()
println("THE RESPONSE WAS : $response.body()")
return@withContext if(response.isSuccessful) response.body()?.toUserSession() else null
LoggingInterceptor 200-OK后的结果:
"expires_in":3600,"token_type":"Bearer","refresh_token":"T1amGR21.IdKM.5ecbf91162691e15913582bf2662e0","access_token":"T1amGT21.Idup.298885bf38e99053dca3434eb59c6aa"
Response.body() 打印结果:
THE RESPONSE WAS : NetUserSession(expires_in=0, token_type=null, refresh_token=null, access_token=null)
有什么我在这里看不到的想法吗?
【问题讨论】:
【参考方案1】:在绞尽脑汁数小时后,解决方案是简单地将模型类的成员从 val
更改为 var
,如下所示:
data class NetUserSession(
@SerializedName("expires_in")
var expires_in: Int = 0,
@SerializedName("token_type")
var token_type: String? = null,
@SerializedName("refresh_token")
var refresh_token: String? = null,
@SerializedName("access_token")
var access_token: String? = null
)
fun toUserSession(): UserSession = UserSession(
expiresIn = expires_in,
tokenType = token_type!!,
refreshToken = refresh_token!!,
accessToken = access_token!!
)
【讨论】:
以上是关于改造 POST 响应转换失败,无影无踪的主要内容,如果未能解决你的问题,请参考以下文章
如何将改造回调响应中的回调从 java 转换为 Kotlin
改造 2:responseBodyConverter 转换为空对象