代码之家  ›  专栏  ›  技术社区  ›  Stelios Papamichail

改装后响应转换失败,无痕迹

  •  0
  • Stelios Papamichail  · 技术社区  · 5 年前

    我正在为一家使用MVVM&clean体系结构的公司构建一个应用程序,因此我创建了3个模块:应用程序模块(表示层)、数据模块(数据层)和域模块(域/交互层)。现在,在我的数据模块中,我使用refrofit和Gson将从登录POST请求接收到的JSON自动转换为您在下面看到的名为NetUserSession的kotlin数据类。我遇到的问题是日志拦截器通常会打印带有数据的响应,但是 response.body()

    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)
        }
    }
    

    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
        }
    }
    

    在200-OK后记录拦截器结果:

    {"expires_in":3600,"token_type":"Bearer","refresh_token":"T1amGR21.IdKM.5ecbf91162691e15913582bf2662e0","access_token":"T1amGT21.Idup.298885bf38e99053dca3434eb59c6aa"}
    

    响应。主体()打印结果:

    THE RESPONSE WAS : NetUserSession(expires_in=0, token_type=null, refresh_token=null, access_token=null)
    

    你知道我没看到什么吗?

    0 回复  |  直到 5 年前
        1
  •  0
  •   Stelios Papamichail    5 年前

    在我绞尽脑汁数小时后,解决方案是简单地将模型类的成员从 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!!
        )
    }