У меня есть API, который возвращает упакованный результат, и я хочу сделать одну универсальную оболочку вместо 20.
Однако я не могу получить значение результата для приведения к моему универсальному типу.
Это код:
По ответу от API:
override fun onResponse(call: Call, response: Response) {
val userResponse = response.getResultAs<UserResponse>()
userResponse?.let { user ->
App.shared.userSettings.edit().putString(UserSettingsKeys.ACTIVE_USER.key,
ObjectMapper().writeValueAsString(user)).apply()
App.shared.userSettings.edit().putString(UserSettingsKeys.TOKEN.key,
response.header("Authorization")).apply()
presenter?.onLoginSuccess(user)
} ?: presenter?.onLoginFailure("No response returned")
}
Расширение для класса результатов:
fun <T> Response.getResultAs(): T? {
this.body()?.string()?.let {
val mapper = jacksonObjectMapper()
val obj = JsonParser().parse(it).asJsonObject.toString()
val baseResponseWrapper: BaseResponseWrapper<T> = mapper.readValue(obj)
when {
baseResponseWrapper.errorValues != null -> {
baseResponseWrapper.logErrorMessage = "invalid credentials"
}
baseResponseWrapper.returnVal == null -> {
baseResponseWrapper.logErrorMessage = "returnVal could not be parsed"
}
else -> {
return baseResponseWrapper.returnVal
}
}
}
return null
}
Класс оболочки ответа:
data class BaseResponseWrapper<T>(
@field:JsonProperty("returnVal")
val returnVal: T? = null,
@field:JsonProperty("errorDescription")
val errorDescription: String? = null,
@field:JsonProperty("errorCode")
val errorCode: Int? = null,
@field:JsonProperty("errorValues")
val errorValues: Any? = null,
var logErrorMessage: String? = null
)
Он анализирует данные в правильно отформатированную карту Linked Hash, а не в моем классе.
Это мое состояние перед сбоем в отладке:
baseResponseWrapper.returnVal = {LinkedHashMap@7400} size = 9
0 = {LinkedHashMap$LinkedHashMapEntry@7409} "isInfluencer" -> "false"
1 = {LinkedHashMap$LinkedHashMapEntry@7410} "currentUserBranchUsername" -> "000"
2 = {LinkedHashMap$LinkedHashMapEntry@7411} "parentUser" -> " size = 4"
3 = {LinkedHashMap$LinkedHashMapEntry@7412} "profile" -> " size = 3"
4 = {LinkedHashMap$LinkedHashMapEntry@7413} "currentUserProfile" -> "null"
5 = {LinkedHashMap$LinkedHashMapEntry@7414} "email" -> "null"
6 = {LinkedHashMap$LinkedHashMapEntry@7415} "userName" -> "null"
7 = {LinkedHashMap$LinkedHashMapEntry@7416} "muviId" -> "null"
8 = {LinkedHashMap$LinkedHashMapEntry@7417} "userId" -> "0000-0000-0000"
и это моя консольная ошибка:
2018-10-29 12: 56: 15,401 1916-1962 / com.appshack.livetree
E / AndroidRuntime: ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: OkHttp Dispatcher
Процесс: com.appshack.livetree, PID: 1916
java.lang.IllegalStateException: закрыто
в okio.RealBufferedSource.rangeEquals (RealBufferedSource.java:408)
в okio.RealBufferedSource.rangeEquals (RealBufferedSource.java:402)
на okhttp3.internal.Util.bomAwareCharset (Util.java:469)
на okhttp3.ResponseBody.string (ResponseBody.java:175)
в com.appshack.livetree.utililty.extensions.OkHttpResult_getResultAsKt.getResultAs (OkHttpResult + getResultAs.kt: 17)
на com.appshack.livetree.ui.outside.login.LoginInteractor $ loginResponseCallback $ 1.onResponse (LoginInteractor.kt: 43)
на okhttp3.RealCall $ AsyncCall.execute (RealCall.java:153)
на okhttp3.internal.NamedRunnable.run (NamedRunnable.java:32)
в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:607)
at java.lang.Thread.run (Thread.java:761)
Я новичок в дженериках, но есть ли способ заставить эту работу?