我使用密封类来处理api响应。我正在尝试一些代码,但得到了一些序列化错误。我也尝试过这个解决方案,但它不起作用。你们能帮我解决这个问题吗。我是序列化领域的新手。
import kotlinx.serialization.Serializable
sealed class ApiResponse<out T : Any> {
data class Success<out T : Any>(
val data: T?
) : ApiResponse<T>()
data class Error(
val exception: Throwable? = null,
val responseCode: Int = -1
) : ApiResponse<Nothing>()
fun handleResult(onSuccess: ((responseData: T?) -> Unit)?,onError: ((error: Error) -> Unit)?) {
when (this) {
is Success -> {
onSuccess?.invoke(this.data)
}
is Error -> {
onError?.invoke(this)
}
}
}
}
@Serializable
data class ErrorResponse(
val errorCode: Int,
val errorMessage: String
)
Api
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.Serializable
class KtorCountryApi(private val httpClient: HttpClient) {
suspend fun getCart(): Flow<ApiResponse<KtorCountriesResponse>> {
println("api call")
return httpClient.get {
url("https://shop-api.example-stg2.com/api/v1/address/country")
}.body()
}
}
@Serializable
data class KtorCountriesResponse(
val items: List<KtorCountry>? = null
)
@Serializable
data class KtorCountry(
val id: String? = null,
val isCurrentCountry: Boolean? = null,
var isoAlpha2Code: String? = null,
var name: String? = null,
var phonePrefix: String? = null,
val usesPerAreaShipping: Boolean? = null
)
客户端
actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(OkHttp) {
config(this)
install(Logging) {
logger = Logger.SIMPLE
level = LogLevel.BODY
}
install(ContentNegotiation) {
json(Json {
prettyPrint = true
ignoreUnknownKeys = true
explicitNulls = false
})
}
engine {
config {
retryOnConnectionFailure(true)
connectTimeout(30, TimeUnit.SECONDS)
readTimeout(40, TimeUnit.SECONDS)
}
}
defaultRequest {
header("Client-Version", Platform().versionCode)
}
install(Auth) {
bearer {
loadTokens {
BearerTokens(tokenProvider.accessToken, "")
}
refreshTokens {
val response =
client.post("https://example-stg2.com/api/v1/session/refresh") {
markAsRefreshTokenRequest()
contentType(ContentType.Application.Json)
setBody(KtorSessionCommand(tokenProvider.refreshToken))
}
if (response.status == HttpStatusCode.Unauthorized) {
null
} else {
val ktorLoginResponse = response.body<KtorLoginResponse>()
ktorLoginResponse.accessToken?.let { ktorAccessToken ->
ktorAccessToken.accessToken?.let { accessToken ->
ktorAccessToken.refreshToken?.let { refreshToken ->
BearerTokens(accessToken, refreshToken)
}
}
}
}
}
}
}
}
错误
2022-04-22 10:50:28.614 8365-8365/com.example.app.dev E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app.dev, PID: 8365
kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null')
JSON input: .....pping":false,"phonePrefix":"263","isCurrentCountry":false}]}
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:32)
at kotlinx.serialization.json.internal.PolymorphicKt.throwSerializerNotFound(Polymorphic.kt:76)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:66)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:100)
at io.ktor.serialization.kotlinx.KotlinxSerializationConverter.deserialize(KotlinxSerializationConverter.kt:55)
at io.ktor.client.plugins.contentnegotiation.ContentNegotiation$Plugin$install$2.invokeSuspend(ContentNegotiation.kt:135)
at io.ktor.client.plugins.contentnegotiation.ContentNegotiation$Plugin$install$2.invoke(Unknown Source:13)
at io.ktor.client.plugins.contentnegotiation.ContentNegotiation$Plugin$install$2.invoke(Unknown Source:6)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.client.HttpClient$4.invokeSuspend(HttpClient.kt:170)
at io.ktor.client.HttpClient$4.invoke(Unknown Source:11)
at io.ktor.client.HttpClient$4.invoke(Unknown Source:6)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.client.plugins.logging.Logging$setupResponseLogging$2.invokeSuspend(Logging.kt:167)
at io.ktor.client.plugins.logging.Logging$setupResponseLogging$2.invoke(Unknown Source:11)
at io.ktor.client.plugins.logging.Logging$setupResponseLogging$2.invoke(Unknown Source:6)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:91)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$2.invokeSuspend(HttpCallValidator.kt:140)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$2.invoke(Unknown Source:13)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$2.invoke(Unknown Source:6)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:101)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.client.call.HttpClientCall.body(HttpClientCall.kt:87)
at com.example.kotlinmultiplatformsharedmodule.KtorCountryApi.getCart(KtorCountryApi.kt:53)
at com.example.kotlinmultiplatformsharedmodule.KtorCountryApi$getCart$1.invokeSuspend(Unknown Source:14)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
我不明白这个错误是什么意思。有人能解释一下为什么我们需要额外的代码来解决这个错误吗?
发布于 2022-04-30 21:39:33
Success
或Error
--进行反序列化,但是没有提供代码的明确方法来根据输入字段区分这两个类所使用的类型。@SerialName
,以帮助服务器端正确地解码它们。https://stackoverflow.com/questions/71968073
复制相似问题